方法簇 用途 典型簽名
序列化 Java → JSON writeValue(File/OutputStream/Writer/StringBuilder, Object)
字符串序列化 Java → JSON String writeValueAsString(Object) / writeValueAsBytes(Object)
反序列化 JSON → Java readValue(File/InputStream/Reader/String/byte[], Class/TypeReference)
樹模型 JSON → JsonNode readTree(String/InputStream/File)
1. 單實體對象雙向轉換
public class Student {
private int id;
private String name;
private boolean isStudent;
// getter/setter/toString
}
Student s = new Student(1000, "小廖", true);
// 對象 -> JSON 文件
mapper.writeValue(new File("student.json"), s);
// 對象 -> JSON 字符串 (控制台輸出)
String json = mapper.writeValueAsString(s);
// {"id":1000,"name":"小廖","isStudent":true}
// JSON 字符串 -> 對象
Student s2 = mapper.readValue(json, Student.class);
// JSON 文件 -> 對象
Student s3 = mapper.readValue(new File("student.json"), Student.class);
2. 集合與數組處理
List 序列化
List list = Arrays.asList(
new Student(1000, "小廖", true),
new Student(200, "小米", false)
);
mapper.writeValue(new File("students.json"), list);
// [{"id":1000,"name":"小廖","isStudent":true},{"id":200,"name":"小米","isStudent":false}]
List 反序列化:TypeReference 必須用
String json = "[{\"id\":1000,\"name\":\"小廖\"},{\"id\":200,\"name\":\"小米\"}]";
// 錯誤:List
List list = mapper.readValue(json,
new TypeReference>() {});
數組反序列化:直接用 Class[]
Student[] arr = mapper.readValue(json, Student[].class);
3. Map 處理
Map map = new LinkedHashMap<>();
map.put("stu1", new Student(1000, "小廖", true));
map.put("stu2", new Student(200, "小米", false));
// Map -> JSON (鍵為 JSON 對象屬性名)
mapper.writeValue(new File("map.json"), map);
// {"stu1":{"id":1000,...},"stu2":{"id":200,...}}
// JSON -> Map (值類型需 TypeReference)
Map parsed = mapper.readValue(new File("map.json"),
new TypeReference>() {});
4. 混合結構處理
// List 包含:字符串、對象、Map、數組
List mixed = new ArrayList<>();
mixed.add("純文本");
mixed.add(new Student(1, "對象", true));
Map m = new HashMap<>();
m.put("key", "value");
mixed.add(m);
mixed.add(new int[]{1,2,3});
mapper.writeValue(System.out, mixed);
// ["純文本",{"id":1,"name":"對象","isStudent":true},{"key":"value"},[1,2,3]]
// 反序列化混合結構 → List / List
List parsed = mapper.readValue(json, new TypeReference>() {});
// 需手動根據類型轉換
5. 日期時間統一格式化
// 關閉時間戳,開啟 ISO 格式
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
// Java 8 LocalDateTime 需註冊模塊
mapper.registerModule(new JavaTimeModule());
// 則自動支持 ISO_LOCAL_DATE_TIME: "2024-01-15T14:30:00"
6. 格式化輸出
// 開啟縮進
mapper.enable(SerializationFeature.INDENT_OUTPUT);
mapper.writeValue(System.out, student);
// 輸出:
// {
// "id" : 1000,
// "name" : "小廖",
// "isStudent" : true
// }
7. 忽略 Null 字段 / 未知字段
// 序列化時忽略 null
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
// 反序列化時忽略 JSON 中多餘字段
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
// 或類上註解 @JsonIgnoreProperties(ignoreUnknown = true)
8. 流式 API 處理超大 JSON (內存友好)
生成大數組文件
try (JsonGenerator gen = mapper.getFactory().createGenerator(new File("huge.json"), JsonEncoding.UTF_8)) {
gen.writeStartArray();
for (int i = 0; i < 1_000_000; i++) {
mapper.writeValue(gen, new Student(i, "User" + i, true));
}
gen.writeEndArray();
}
// 內存佔用極低,不創建中間 List/String
解析大數組流式讀取
try (JsonParser parser = mapper.getFactory().createParser(new File("huge.json"))) {
if (parser.nextToken() == JsonToken.START_ARRAY) {
while (parser.nextToken() == JsonToken.START_OBJECT) {
Student s = mapper.readValue(parser, Student.class);
process(s); // 逐個處理,隨用隨釋放
}
}
}
9. 樹模型 (JsonNode) 動態操作
JsonNode root = mapper.readTree(jsonString);
String name = root.path("name").asText(); // 安全獲取,缺失返回 ""
JsonNode skills = root.path("skills");
if (skills.isArray()) {
for (JsonNode skill : skills) System.out.println(skill.asText());
}
// 修改
((ObjectNode) root).put("age", 25).putArray("tags").add("java").add("json");
// 輸出
String modified = mapper.writeValueAsString(root);
10. 性能優化關鍵配置
// 單例!全局唯一
public static final ObjectMapper MAPPER = new ObjectMapper()
.registerModule(new JavaTimeModule()) // Java 8 時間
.registerModule(new AfterburnerModule()) // 字節碼加速 (可選)
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.setSerializationInclusion(JsonInclude.Include.NON_NULL)
.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"))
.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE); // 駝峰<->下劃線
總結
ObjectMapper 是 Jackson 的瑞士軍刀。核心記住:單例複用 、容器反序列化必用 TypeReference 、日期註冊 JavaTimeModule 、大文件用流式 API 、配置容錯 (忽略未知/Null) 。掌握上述 10 大場景,覆蓋 95% 日常 JSON 處理需求。
上一篇文章: Java 8 接口默認方法與靜態方法全解析:演進動機、多重實現衝突解決與最佳實踐 下一篇文章: Jemalloc 優化 MySQL 與 Nginx 內存分配性能實戰指南
Copyright ©
程式碼之家 All Rights Reserved