1. 概述
Jackson-jr 是一個輕量級的 Java JSON 處理庫,旨在提供比原始 Jackson 庫更簡單、更小的替代方案。憑藉其小巧的佔位符和易於使用的 API,Jackson-jr 是 休閒 JSON 讀取和寫入場景的絕佳選擇。
在本指南中,我們將探索 Jackson-jr 的關鍵功能和用法,以及示例和最佳實踐。
2. 快速入門 Jackson-jr
Jackson-jr 提供了一種輕量級且高效的方式來處理 Java 應用程序中的 JSON 數據。它提供了一個簡單的 API,用於與 JSON 對象和數組進行交互,從而更輕鬆地解析、生成和操作 JSON 數據。
首先,我們需要將 Jackson-jr 庫包含到我們的項目中。我們可以通過將所需的 Jackson-jr 版本依賴添加到項目的構建配置文件的其中。
對於 Maven,我們可以將依賴添加到我們的 pom.xml 文件中:
<dependency>
<groupId>com.fasterxml.jackson.jr</groupId>
<artifactId>jackson-jr-all</artifactId>
<version>2.15.2</version>
</dependency>
對於 Gradle,我們可以將依賴添加到我們的 build.gradle 文件中:
implementation 'com.fasterxml.jackson.jr:jackson-jr-all:2.15.2'
3. 工作與 JSON 對象
用於與 Jackson-jr 協作的基礎對象是 JSON 對象。 關於 JSON 對象 的一個非常重要且不可忘記的事實是:每個 JSON 實例都是完全不可變且線程安全的。 我們可以以任何方式使用它們,例如作為單例實例、Spring Bean,甚至可以構造單個對象。 我們可以將同一實例傳遞給不同的線程,因為它完全不可變。
3.1. 創建 JSON 對象和數組
創建 JSON 對象和數組:Jackson-jr 提供了一個方便的 API 用於創建 JSON 對象和數組。 我們可以使用諸如 LinkedHashMap 類來表示 JSON 對象,以及 ArrayList 來表示 JSON 數組。
JSON 對象是 LinkedHashMap。 我們可以使用 LinkedHashMap.put() 方法輕鬆添加屬性,並使用 LinkedHashMap.get() 方法獲取屬性。
String json = JSON.std
.with(JSON.Feature.PRETTY_PRINT_OUTPUT)
.asString(new LinkedHashMap<String, Object>() {{
put("name", "John Doe");
put("age", 30);
put("email", "[email protected]");
}});
3.2. Jackson-jr 編排器
Jackson-jr 的另一個不錯的功能是添加了 編排器 接口,用於以 Builder- 風格生成 JSON 內容:
String json = JSON.std.with(JSON.Feature.PRETTY_PRINT_OUTPUT)
.composeString()
.startObject()
.startArrayField("objectArray")
.startObject()
.put("name", "name1")
.put("age", 11)
.end()
.startObject()
.put("name", "name2")
.put("age", 12)
.end()
.end()
.startArrayField("array")
.add(1)
.add(2)
.add(3)
.end()
.startObjectField("object")
.put("name", "name3")
.put("age", 13)
.end()
.put("last", true)
.end()
.finish();
這個 Builder 結果如下 JSON:
{
"objectArray" : [ {
"name" : "name1",
"age" : 11
}, {
"name" : "name2",
"age" : 12
} ],
"array" : [ 1, 2, 3 ],
"object" : {
"name" : "name3",
"age" : 13
},
"last" : true
}
4. 序列化和反序列化
Jackson-jr 允許我們輕鬆地將 Java 對象轉換為 JSON 字符串,反之亦然。我們可以配置寫入器,以指定所需的選項,例如漂亮的打印或自定義日期格式,然後使用它將對象寫入 JSON 字符串。
Jackson-jr 支持複雜對象結構,包括嵌套對象和數組。通過正確定義 Java 類及其關係,Jackson-jr 可以處理複雜的 JSON 數據的序列化和反序列化。
// 序列化
String json = JSON.std.with(JSON.Feature.PRETTY_PRINT_OUTPUT)
.asString(person);
// 反序列化
json = "{\"name\":\"John Doe\",\"age\":30}";
Person person1 = JSON.std.with(JSON.Feature.PRETTY_PRINT_OUTPUT)
.beanFrom(Person.class, json);
4.1. Jackson-jr 中的自定義配置
Jackson-jr 支持各種註解,例如 @JsonProperty,以自定義序列化和反序列化過程。這些註解允許我們控制屬性名稱、指定日期和時間格式以及處理其他自定義場景。我們可以查看所有受支持的註解在它們的 官方 Github 項目中。
Jackson-jr 具有我們可以在序列化和反序列化輸入和輸出中使用的一系列特性自定義,例如漂亮的打印、寫入空屬性等。最簡單的方法是在基本代碼中查看所有這些。
JSON jsonMapper = JSON.std.with(JSON.Feature.PRETTY_PRINT_OUTPUT)
.with(JSON.Feature.WRITE_NULL_PROPERTIES)
.with(JSON.Feature.FAIL_ON_DUPLICATE_MAP_KEYS);
String json = jsonMapper.asString(person);
Jackson-jr 允許我們創建自定義序列化器和反序列器來處理特定數據類型或複雜的序列化場景。通過實現適當的接口,ValueWriter,並擴展提供的類,ValueReader and ReadWriterProvider,我們可以定義自定義對象如何序列化和反序列化。
Jackson-jr 不支持 java.time.* 包,但我們可以使用自定義序列化器和反序列器添加它:
public class CustomDateSerializer implements ValueWriter {
@Override
public void writeValue (JSONWriter jsonWriter, JsonGenerator jsonGenerator, Object o) throws IOException {
jsonGenerator.writeString(o.toString());
}
@Override
public Class<?> valueType () {
return LocalDate.class;
}
}
public class CustomDateDeserializer extends ValueReader {
private final static DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MMM-dd");
public CustomDateDeserializer () {
super(LocalDate.class);
}
@Override
public Object read (JSONReader jsonReader, JsonParser jsonParser) throws IOException {
return LocalDate.parse(jsonParser.getText(), dtf);
}
}
在註冊它們之後,我們可以開始序列化和反序列化 LocalDate 對象:
public class MyHandlerProvider extends ReaderWriterProvider {
@Override
public ValueWriter findValueWriter (JSONWriter writeContext, Class<?> type) {
if (type == LocalDate.class) {
return new CustomDateSerializer();
}
return null;
}
@Override
public ValueReader findValueReader (JSONReader readContext, Class<?> type) {
if (type.equals(LocalDate.class)) {
return new CustomDateDeserializer();
}
return null;
}
}
Person person = new Person("John Doe", 30, LocalDate.now());
JSON jsonMapper = JSON.builder().register(new JacksonJrExtension() {
@Override
protected void register (ExtensionContext extensionContext) {
extensionContext.insertProvider(new MyHandlerProvider());
}
}).build().with(JSON.Feature.PRETTY_PRINT_OUTPUT);
String json = jsonMapper.asString(person);
Person deserializedPerson = jsonMapper.beanFrom(Person.class, json);
5. Jackson-jr 與 Jackson
| Jackson-jr | Jackson |
|---|---|
| 較小的 jar | 較大的 jar |
| 更少的特性 | 更復雜的特性 |
| 更適合簡單的序列化和反序列化 | 更適合更復雜的序列化和反序列化 |
| 更快的啓動時間 | 較慢的啓動時間 |
| 更簡單的 API | 更復雜的 API |
6. 結論
Jackson-jr 提供了一種輕量級且用户友好的 JSON 處理方法,適用於 Java 應用程序。憑藉其簡化的 API、自定義選項和高效的性能,它對於需要輕量級 JSON 處理庫,同時又不影響功能性的開發者來説,是一個極佳的選擇。