Jackson 核心入口,線程安全,可復用單例:
ObjectMapper mapper = new ObjectMapper();
// 常用配置
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
List list = Arrays.asList(1, 2, 3);
String json = mapper.writeValueAsString(list);
// 輸出: [1,2,3]
public class Student {
private int age = 10;
private String name = "hhh";
private String[] list = {"hao", "haouhao", "keyi"};
private Date time = new Date();
// Getter/Setter...
}
Student st = new Student();
String json = mapper.writeValueAsString(st);
// 輸出: {"list":["hao","haouhao","keyi"],"time":1375429228382,"name":"hhh","age":10}
// 方式一:全局配置 ISO-8601
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
// 輸出: "time":"2013-08-02T03:48:20.000+0000"
// 方式二:自定義格式
mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
// 輸出: "time":"2013-08-02 03:48:20"
// 方式三:註解級控制
public class Student {
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date time;
}
JsonGenerator generator = mapper.getFactory().createGenerator(new File("student.json"), JsonEncoding.UTF8);
generator.writeObject(st);
generator.close();
優勢:低內存佔用、支持寫入 OutputStream、文件、網絡流
String json = "{\"objectID\":357,\"geoPoints\":[{\"x\":504604.598,\"y\":305569.915}]}";
public class GeoData {
public int objectID;
public List geoPoints = new ArrayList<>();
public static class Point { public double x; public double y; }
}
GeoData data = mapper.readValue(json, GeoData.class);
// 訪問: data.objectID, data.geoPoints.get(0).x
String json = "{\"error\":0,\"data\":{\"name\":\"ABC\",\"age\":20}}";
Map map = mapper.readValue(json, Map.class);
// 訪問: map.get("error"), ((Map)map.get("data")).get("name")
String json = "{\"results\":[{\"objectID\":357,\"geoPoints\":[{\"x\":504604.598,\"y\":305569.915}]},{\"objectID\":358,\"geoPoints\":[{\"x\":504602.268,\"y\":305554.436}]}]}";
JsonNode root = mapper.readTree(json);
JsonNode results = root.get("results");
for (JsonNode item : results) {
int objectID = item.get("objectID").asInt();
JsonNode points = item.get("geoPoints");
for (JsonNode point : points) {
double x = point.get("x").asDouble();
double y = point.get("y").asDouble();
System.out.println(objectID + " " + x + " " + y);
}
}
// 輸出:
// 357 504604.598 305569.915
// 358 504602.268 305554.436
特點:結構清晰、按需提取、但需全量加載內存
| 註解 | 用途 |
|---|---|
@JsonProperty | 字段名映射 |
@JsonIgnore | 忽略字段 |
@JsonFormat | 日期/數字格式 |
@JsonInclude | 控制 null/空值輸出 |
@JsonCreator | 構造器/工廠方法綁定 |
@JsonSubTypes | 多態反序列化 |
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(value = Dog.class, name = "dog"),
@JsonSubTypes.Type(value = Cat.class, name = "cat")
})
public abstract class Animal { ... }
// 避免 LazyInitializationException
mapper.registerModule(new Hibernate5Module());
JsonParser/JsonGenerator 避免全量內存FAIL_ON_UNKNOWN_PROPERTIES、WRITE_DATES_AS_TIMESTAMPS| 問題 | 原因 | 解決 |
|---|---|---|
| 日期輸出時間戳 | 默認 WRITE_DATES_AS_TIMESTAMPS=true | 配置 false 或 @JsonFormat |
| 反序列化缺少無參構造器 | POJO 無默認構造器 | 添加無參構造器或 @JsonCreator |
| 未知屬性報錯 | JSON 包含類中無的字段 | 配置 FAIL_ON_UNKNOWN_PROPERTIES=false |
| 循環引用導致 StackOverflow | 雙向關聯未斷開 | @JsonIgnore/@JsonManagedReference/@JsonBackReference |
| 泛型類型擦除 | List<T> 運行時類型丟失 | 使用 TypeReference 或 JavaType |
Jackson 是 Java 生態最強大的 JSON 處理庫,提供數據綁定、樹模型、流式 API 三種範式。掌握 ObjectMapper 配置、日期格式控制、多態處理、性能優化與常見坑點,能高效解決企業級應用中 99% 的 JSON 處理需求。