首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Jackson 數據綁定完全指南:簡易綁定、全數據綁定與 ObjectMapper 核心用法

     編輯:Java 相關知識

Jackson 體系概覽

Jackson 是 Java 生態最流行的 JSON 庫,核心三模組:

  • jackson-core:流式解析/生成(JsonParser/JsonGenerator),零依賴,高性能。
  • jackson-annotations:註解定義(@JsonProperty 等)。
  • jackson-databind:數據綁定層,基於核心流 API 實現 POJO ⇄ JSON 雙向轉換,核心類 ObjectMapper。

兩種數據綁定模式

1. 簡易數據綁定

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"); // 需強轉

類型對應表:

JSONJava
objectLinkedHashMap
arrayArrayList
stringString
number (int)Integer / Long / BigInteger
number (float)Double / BigDecimal
true/falseBoolean
nullnull

2. 全數據綁定

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 核心配置

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);

進階技巧

1. 泛型容器反序列化:TypeReference

String json = "[{\"id\":1},{\"id\":2}]";
// 錯誤:List 會丟失泛型信息
// 正確:匿名內部類保留泛型類型
List> list = mapper.readValue(json, 
    new TypeReference>>() {});

2. 多態反序列化:@JsonTypeInfo

@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

3. 自定義序列化器/反序列化器

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;

4. 流式 API 處理超大 JSON(低內存)

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
反序列化報 UnrecognizedPropertyExceptionJSON 有多餘字段配置 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 反序列化

性能優化建議

  1. 單例複用 ObjectMapper:線程安全,創建開銷大(註解掃描、序列化器緩存)。
  2. 避免頻繁 writeValueAsString:大對象直接 writeValue(OutputStream, obj) 避免中間字符串。
  3. 啟用 Afterburner 模組:mapper.registerModule(new AfterburnerModule()),字節碼生成替代反射,提速 20-30%。
  4. 大數組流式寫入:mapper.writeValue(new File("out.json"), hugeList) 內部已優化為流式,不全量進內存。

總結

Jackson 以 ObjectMapper 為核心,提供從簡易動態綁定到強類型 POJO 綁定的完整譜系。掌握 TypeReference、多態註解、自定義 (De)Serializer、流式 API 及核心配置項,即可應對 99% JSON 處理場景。生產環境務必單例複用、配置容錯屬性、關注日期與枚舉策略、防範循環引用。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved