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

Jackson 庫核心用法與樹模型深度解析

     編輯:Java 相關知識

前言

Jackson 是 Java 生態系中最主流的 JSON 處理庫,提供三種核心處理模式:資料綁定、樹模型、流式 API。本文重點解析資料綁定與樹模型的實戰應用,並提供完整可執行範例。

環境準備

Maven 依賴 (Jackson 1.x 版本,現代專案建議升級至 2.x):

<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-mapper-asl</artifactId>
    <version>1.9.13</version>
</dependency>

核心類:ObjectMapper

ObjectMapper 是 Jackson 的核心進入點,線程安全且可重複使用,建議作為單例管理:

// 單例模式最佳實踐
public class JacksonUtil {
    private static final ObjectMapper MAPPER = new ObjectMapper();
    static {
        MAPPER.enable(SerializationFeature.INDENT_OUTPUT); // 格式化輸出
        MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); // 忽略未知屬性
    }
    public static ObjectMapper getMapper() { return MAPPER; }
}

模式一:資料綁定 - POJO 雙向轉換

定義實體類

public class Student {
    private String name;
    private int age;
    // Getter/Setter/建構子/toString 省略
}

序列化與反序列化

ObjectMapper mapper = JacksonUtil.getMapper();

// JSON → POJO
String json = "{\"name\":\"Mahesh\", \"age\":21}";
Student student = mapper.readValue(json, Student.class);
System.out.println(student); // Student [name: Mahesh, age: 21]

// POJO → JSON
String output = mapper.writeValueAsString(student);
System.out.println(output); 
// 輸出:
// {
//   "name" : "Mahesh",
//   "age" : 21
// }

模式二:樹模型 - JsonNode 靈活操作

樹模型適合結構不固定、無對應 POJO、或需部分提取/修改的場景,類似 XML DOM 解析。

1. 從 JSON 建立樹結構

String json = "{\"name\":\"Mahesh Kumar\", \"age\":21, \"verified\":false, \"marks\":[100,90,85]}";
JsonNode rootNode = mapper.readTree(json);

2. 節點遍歷與值提取

// 簡單欄位
String name = rootNode.path("name").asText();        // "Mahesh Kumar"
int age = rootNode.path("age").asInt();              // 21
boolean verified = rootNode.path("verified").asBoolean(); // false

// 陣列節點遍歷
JsonNode marksNode = rootNode.path("marks");
for (JsonNode mark : marksNode) {
    System.out.print(mark.asInt() + " "); // 100 90 85
}

// 安全導航:節點不存在時返回 MissingNode,不拋異常
String missing = rootNode.path("address").asText("N/A"); // "N/A"

3. 程式化建構樹結構

ObjectNode root = mapper.createObjectNode();
ArrayNode marks = mapper.createArrayNode();
marks.add(100).add(90).add(85);

root.put("name", "Mahesh Kumar");
root.put("age", 21);
root.put("verified", false);
root.set("marks", marks); // 陣列用 set

// 寫入檔案
mapper.writeValue(new File("student.json"), root);

4. 樹模型 ↔ POJO 互轉

// JsonNode → POJO (需目標類有預設建構子)
Student student = mapper.treeToValue(rootNode, Student.class);

// POJO → JsonNode
JsonNode node = mapper.valueToTree(student);

進階技巧與最佳實踐

日期時間處理

// Java 8 LocalDateTime
mapper.registerModule(new JavaTimeModule());
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); // 輸出 ISO-8601 字串

忽略 Null 值

mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

自定義序列化器

public class MaskingSerializer extends JsonSerializer {
    @Override
    public void serialize(String value, JsonGenerator gen, SerializerProvider provider) throws IOException {
        if (value != null && value.length() > 4) {
            gen.writeString(value.substring(0, 2) + "***" + value.substring(value.length() - 2));
        } else {
            gen.writeString(value);
        }
    }
}

// 使用
@JsonSerialize(using = MaskingSerializer.class)
private String idNumber;

多態反序列化

@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 { ... }

效能優化建議

  • 重用 ObjectMapper:避免重複建立昂貴的映射器實例
  • 使用 afterburner 模組:mapper.registerModule(new AfterburnerModule()) 透過字節碼生成加速存取
  • 流式 API 處理大檔案:JsonParser/JsonGenerator 低記憶體佔用
  • 啟用索引:mapper.enable(DeserializationFeature.USE_JAVA_ARRAY_FOR_JSON_ARRAY)

常見坑點避雷

問題原因解決
反序列化失敗:No suitable constructor缺少無參建構子加上 @JsonCreator 或提供預設建構子
日期輸出為時間戳預設 WRITE_DATES_AS_TIMESTAMPS=truedisable 該特性並註冊 JavaTimeModule
未知屬性拋異常FAIL_ON_UNKNOWN_PROPERTIES=trueconfigure 為 false
循環引用 StackOverflow雙向關係@JsonManagedReference/@JsonBackReference 或 @JsonIdentityInfo
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved