Java 原生序列化無法跨語言、格式固定、不安全。實戰中廣泛使用 Jackson 支持 JSON、XML、MessagePack 等多種格式,實現高性能、可配置、跨語言的數據交換。本文系統講解 Jackson 核心用法、容器對象處理、復雜對象映射、定制序列化註解、XML 局限性等。
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.5</version>
</dependency>
<!-- XML 支持 -->
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.8.5</version>
</dependency>
<!-- MessagePack 支持 -->
<dependency>
<groupId>org.msgpack</groupId>
<artifactId>msgpack-jackson</artifactId>
<version>0.8.11</version>
</dependency>
new ObjectMapper()new XmlMapper() (繼承 ObjectMapper)new ObjectMapper(new MessagePackFactory())// 序列化
Student student = new Student("張三", 18, 80.9d);
ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT); // 格式化輸出
String json = mapper.writeValueAsString(student);
mapper.writeValue(new File("student.json"), student); // 寫文件
// 反序列化
Student s = mapper.readValue(new File("student.json"), Student.class);
// 亦支持 readValue(InputStream/Reader/String/byte[], Class)
輸出 JSON:
{
"name" : "張三",
"age" : 18,
"score" : 80.9
}
list = mapper.readValue(new File("students.json"),
new TypeReference>() {});
// Map 同理
Map map = new HashMap<>();
map.put("zhangsan", new Student("張三",18,80.9));
mapper.writeValue(new File("students_map.xml"), map); // XML 格式
Map map2 = mapper.readValue(new File("students_map.xml"),
new TypeReference
場景 註解方案 ObjectMapper 配置方案
忽略字段(如 transient) @JsonIgnore (字段/方法) / @JsonIgnoreProperties("field") (類) mapper.setSerializationInclusion(Include.NON_NULL) 等
保持對象引用同一性 @JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="id") mapper.enable(SerializationFeature.USE_OBJECT_ID)
解決循環引用 @JsonManagedReference (主引用) + @JsonBackReference (反向引用) 無直接配置,需註解
反序列化忽略未知字段 @JsonIgnoreProperties(ignoreUnknown=true) (類) mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
支持多態/繼承類型信息 @JsonTypeInfo + @JsonSubTypes (基類) mapper.activateDefaultTyping()
修改字段名稱(如中文) @JsonProperty("中文名") mapper.setPropertyNamingStrategy()
修改 XML 根元素名 @JsonRootName("student") mapper.enable(SerializationFeature.WRAP_ROOT_VALUE)
格式化日期輸出 @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss", timezone="GMT+8") mapper.setDateFormat(new SimpleDateFormat(...))
指定構造方法反序列化 @JsonCreator + @JsonProperty (構造方法參數) 無直接配置
關鍵註解實戰示例
Jackson XML 支持的已知局限性
Map<String, List<String>> 等嵌套泛型容器:可序列化,但無法反序列化(拋異常)。此類場景建議改用 XStream (https://x-stream.github.io/) 或避免在 XML 中使用復雜嵌套泛型。
總結
Jackson 以 ObjectMapper 為核心、註解為配置、多格式統一 API,實現了優雅的跨語言序列化。掌握 TypeReference 處理容器、註解定制行為、XML 局限規避,即可應對 99% 實戰場景。註解如何改變程序行為?留待後續章節揭秘「註解處理器與反射」原理。