<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.17.0</version>
</dependency>
<!-- 可選:Java 8 時間模組 -->
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.17.0</version>
</dependency>
package com.example.util;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import java.text.SimpleDateFormat;
public final class JsonUtils {
// 單例 ObjectMapper,線程安全
private static final ObjectMapper MAPPER = new ObjectMapper();
static {
// 1. 忽略未知字段,避免反序列化報錯
MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
// 2. 日期統一格式化
MAPPER.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
// 3. 註冊 Java 8 時間模組(LocalDateTime 等)
MAPPER.registerModule(new JavaTimeModule());
// 4. 序列化日期為時間戳關閉,改用字符串
MAPPER.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
// 5. 格式化輸出(開發調試用,生產可關閉)
MAPPER.enable(SerializationFeature.INDENT_OUTPUT);
}
private JsonUtils() {}
/** 對象 → JSON 字符串 */
public static String toJson(Object value) {
try {
return MAPPER.writeValueAsString(value);
} catch (JsonProcessingException e) {
throw new RuntimeException("JSON 序列化失敗", e);
}
}
/** JSON 字符串 → 對象 (指定 Class) */
public static <T> T toObject(String json, Class<T> clazz) {
try {
return MAPPER.readValue(json, clazz);
} catch (JsonProcessingException e) {
throw new RuntimeException("JSON 反序列化失敗", e);
}
}
/** JSON 字符串 → 對象 (複雜泛型,如 List<User>) */
public static <T> T toObject(String json, com.fasterxml.jackson.core.type.TypeReference<T> typeRef) {
try {
return MAPPER.readValue(json, typeRef);
} catch (JsonProcessingException e) {
throw new RuntimeException("JSON 反序列化失敗", e);
}
}
/** 獲取 ObjectMapper 實例(高級自定義場景) */
public static ObjectMapper getMapper() {
return MAPPER;
}
}
public class JsonUtilsDemo {
static class User {
private Long id;
private String name;
private java.time.LocalDateTime createTime;
// getter/setter/toString 省略
}
public static void main(String[] args) {
User u = new User();
u.setId(1L);
u.setName("Alice");
u.setCreateTime(java.time.LocalDateTime.now());
// 1. 對象 → JSON
String json = JsonUtils.toJson(u);
System.out.println("JSON: " + json);
// {"id":1,"name":"Alice","createTime":"2024-05-20 14:30:00"}
// 2. JSON → 對象
User u2 = JsonUtils.toObject(json, User.class);
System.out.println("Object: " + u2);
// 3. 列表轉換
String listJson = "[{\"id\":1,\"name\":\"A\"},{\"id\":2,\"name\":\"B\"}]";
java.util.List<User> list = JsonUtils.toObject(listJson,
new com.fasterxml.jackson.core.type.TypeReference<java.util.List<User>>() {});
System.out.println("List: " + list);
}
}
| 需求 | 配置方式 |
|---|---|
| 忽略 Null 字段 | MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL) |
| 駝峰 ↔ 下劃線自動映射 | MAPPER.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE) |
| 枚舉序列化為名稱 | MAPPER.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING) |
| 單引號/非標準 JSON 兼容 | MAPPER.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true) |
| 大數字不丟失精度 | MAPPER.configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, true) |
封裝線程安全的 ObjectMapper 單例,提供泛型友好的雙向轉換方法,是 Java 後端處理 JSON 的標準做法。Jackson 生態豐富、效能優異,建議作為首選方案。