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 對象 的一個非常重要且不容忽視的事實是:每一個 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 的 Composer 接口
Jackson-jr 的另一個亮點是添加了 Composer 接口,用於以 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();此構建器生成以下 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 數據的序列化和反序列化。
// Serialization
String json = JSON.std.with(JSON.Feature.PRETTY_PRINT_OUTPUT)
.asString(person);
// Deserialization
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 支持多種註解,例如 <em >@JsonProperty</em>,以自定義序列化和反序列化過程。這些註解允許我們控制屬性名稱、指定日期和時間格式以及處理其他自定義場景。我們可以在其官方 GitHub 項目中查看所有支持的註解:https://github.com/FasterXML/jackson-jr/tree/2.16/jr-annotation-support。
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 和 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 vs. Jackson
| Jackson-jr | Jackson |
|---|---|
| 較小的 jar | 較大的 jar |
| 更少的特性 | 更復雜的特性 |
| 更適合簡單的序列化和反序列化 | 更適合更復雜的序列化和反序列化 |
| 更快的啓動時間 | 較慢的啓動時間 |
| 更簡單的 API | 更復雜的 API |
6. 結論
Jackson-jr 提供了一種輕量級且易於使用的 Java 應用程序中 JSON 處理方法。憑藉其簡化的 API、自定義選項和高效的性能,它對於需要輕量級 JSON 處理庫,同時又不犧牲功能性的開發者來説,是一個極佳的選擇。