Jackson 是 Java 生態最流行的 JSON 庫,核心三模組:
JsonParser/JsonGenerator),零依賴,高性能。@JsonProperty 等)。ObjectMapper。JSON ↔ Java 內置類型:Map、List、String、包裝類、null。無需定義 POJO,動態結構處理首選。
ObjectMapper mapper = new ObjectMapper();
// Java 對象 -> JSON 文件/字符串
Map data = new HashMap<>();
data.put("name", "張三");
data.put("age", 25);
data.put("skills", Arrays.asList("Java", "Go"));
data.put("active", true);
mapper.writeValue(new File("user.json"), data);
// 輸出: {"name":"張三","age":25,"skills":["Java","Go"],"active":true}
// JSON -> Java 內置類型
Map parsed = mapper.readValue(new File("user.json"), Map.class);
List skills = (List) parsed.get("skills"); // 需強轉
類型對應表:
| JSON | Java |
|---|---|
| object | LinkedHashMap |
| array | ArrayList |
| string | String |
| number (int) | Integer / Long / BigInteger |
| number (float) | Double / BigDecimal |
| true/false | Boolean |
| null | null |
JSON ↔ 自定義 POJO。類型安全、無需強轉、支持註解精細控制,業務開發主流模式。
// POJO 定義
@Data @NoArgsConstructor @AllArgsConstructor
public class User {
private String name;
private int age;
private List skills;
private boolean active;
}
// 序列化
User user = new User("李四", 30, Arrays.asList("Spring", "K8s"), true);
String json = mapper.writeValueAsString(user);
// 反序列化
User parsed = mapper.readValue(json, User.class); // 直接得到強類型對象
ObjectMapper mapper = new ObjectMapper()
// 格式化輸出
.enable(SerializationFeature.INDENT_OUTPUT)
// 忽略未知字段(反序列化時 JSON 有 POJO 無的字段)
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
// 忽略空值字段(序列化時 null 不輸出)
.setSerializationInclusion(JsonInclude.Include.NON_NULL)
// 日期統一格式
.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"))
// 驼峰屬性名自動映射下劃線 JSON 字段
.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE)
// 支持單引號、非引號字段名等寬鬆模式
.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true)
.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
String json = "[{\"id\":1},{\"id\":2}]";
// 錯誤:List
@JsonTypeInfo(use = Id.NAME, include = As.PROPERTY, property = "type")
@JsonSubTypes({
@Type(value = Cat.class, name = "cat"),
@Type(value = Dog.class, name = "dog")
})
interface Animal { String sound(); }
// JSON: {"type":"cat","name":"Kitty"} -> 自動實例化 Cat
public class LocalDateTimeSerializer extends JsonSerializer {
@Override public void serialize(LocalDateTime v, JsonGenerator g, SerializerProvider p) throws IOException {
g.writeString(v.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
}
}
// 使用
@JsonSerialize(using = LocalDateTimeSerializer.class)
private LocalDateTime createTime;
try (JsonParser parser = mapper.getFactory().createParser(new File("huge.json"))) {
while (parser.nextToken() != JsonToken.END_ARRAY) {
if (parser.currentToken() == JsonToken.START_OBJECT) {
User u = mapper.readValue(parser, User.class); // 逐個對象讀取
process(u);
}
}
}
| 問題 | 原因 | 解決 |
|---|---|---|
| 日期序列化為時間戳數字 | 默認配置 | 配置 SerializationFeature.WRITE_DATES_AS_TIMESTAMPS = false + 設置 DateFormat |
| 反序列化報 UnrecognizedPropertyException | JSON 有多餘字段 | 配置 FAIL_ON_UNKNOWN_PROPERTIES = false 或類上 @JsonIgnoreProperties(ignoreUnknown=true) |
| Map Key 非 String 報錯 | JSON 規範 Key 必須字符串 | 啟用 MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES 或自定義 KeyDeserializer |
| 循環引用 StackOverflowError | 雙向關聯 | @JsonManagedReference/@JsonBackReference 或 @JsonIdentityInfo |
| Enum 序列化為數字/大寫 | 默認 name() | @JsonValue 返回自定義值,或 @JsonCreator 反序列化 |
writeValue(OutputStream, obj) 避免中間字符串。mapper.registerModule(new AfterburnerModule()),字節碼生成替代反射,提速 20-30%。mapper.writeValue(new File("out.json"), hugeList) 內部已優化為流式,不全量進內存。Jackson 以 ObjectMapper 為核心,提供從簡易動態綁定到強類型 POJO 綁定的完整譜系。掌握 TypeReference、多態註解、自定義 (De)Serializer、流式 API 及核心配置項,即可應對 99% JSON 處理場景。生產環境務必單例複用、配置容錯屬性、關注日期與枚舉策略、防範循環引用。