1. Overview
長期以來,Java中JSON處理的標準缺乏。用於JSON處理最常用的庫是Jackson和Gson。
最近,Java EE7帶來了JSON解析和生成API(JSR 353: Java API for JSON Processing)。
最後,在JEE 8發佈後,出現了標準化的API(JSR 367: Java API for JSON Binding (JSON-B))。
目前,其主要實現是Eclipse Yasson (RI)和Apache Johnzon。
2. JSON-B API
2.1 Maven 依賴
讓我們先添加所需的依賴。
請注意,在許多情況下,只需包含所選實現的依賴項,並且 javax.json.bind-api 將會轉隱式包含:
<dependency>
<groupId>javax.json.bind</groupId>
<artifactId>javax.json.bind-api</artifactId>
<version>1.0</version>
</dependency>最新版本可以在 Maven Central 找到。
3. 使用 Eclipse Yasson
Eclipse Yasson 是 JSON Binding API 的官方參考實現 (JSR-367).
3.1. Maven 依賴
要使用它,我們需要將以下依賴項包含在我們的 Maven 項目中:
<dependency>
<groupId>org.eclipse</groupId>
<artifactId>yasson</artifactId>
<version>1.0.1</version>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.json</artifactId>
<version>1.1.2</version>
</dependency>最新版本可以在 Maven Central 找到。
4. 使用 Apache Johnzon
另一個我們可以使用的實現是 Apache Johnzon,它符合 JSON-P (JSR-353) 和 JSON-B (JSR-367) API。
4.1. Maven 依賴
要使用它,我們需要在我們的 Maven 項目中包含以下依賴項:
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-json_1.1_spec</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.apache.johnzon</groupId>
<artifactId>johnzon-jsonb</artifactId>
<version>1.1.4</version>
</dependency>最新版本可以在 Maven Central 找到。
5. API 功能
API 提供註解,用於自定義序列化/反序列化。
讓我們創建一個簡單的類,並查看示例配置如下所示:
public class Person {
private int id;
@JsonbProperty("person-name")
private String name;
@JsonbProperty(nillable = true)
private String email;
@JsonbTransient
private int age;
@JsonbDateFormat("dd-MM-yyyy")
private LocalDate registeredDate;
private BigDecimal salary;
@JsonbNumberFormat(locale = "en_US", value = "#0.0")
public BigDecimal getSalary() {
return salary;
}
// standard getters and setters
}序列化後,該類的對象將看起來像:
{
"email":"[email protected]",
"id":1,
"person-name":"Jhon",
"registeredDate":"07-09-2019",
"salary":"1000.0"
}此處使用的註解如下:
- @JsonbProperty – 用於指定自定義字段名稱
- @JsonbTransient – 當我們希望在反序列化/序列化過程中忽略該字段時
- @JsonbDateFormat – 用於定義日期的顯示格式
- @JsonbNumberFormat – 用於指定數值值的顯示格式
- @JsonbNillable – 用於啓用空值序列化
5.1. 序列化與反序列化
首先,為了獲取我們對象的 JSON 表示,我們需要使用 <em class="textit">JsonbBuilder</em 類及其 <em class="textit">toJson()</em 方法。
接下來,讓我們創建一個簡單的 <em class="textit">Person</em 對象,如下所示:
Person person = new Person(
1,
"Jhon",
"[email protected]",
20,
LocalDate.of(2019, 9, 7),
BigDecimal.valueOf(1000));並且,實例化 Jsonb 類:
Jsonb jsonb = JsonbBuilder.create();然後,我們使用 toJson 方法:
String jsonPerson = jsonb.toJson(person);要獲取以下 JSON 格式的表示:
{
"email":"[email protected]",
"id":1,
"person-name":"Jhon",
"registeredDate":"07-09-2019",
"salary":"1000.0"
}如果我們要進行轉換,可以使用 fromJson 方法:
Person person = jsonb.fromJson(jsonPerson, Person.class);當然,我們還可以處理集合:
List<Person> personList = Arrays.asList(...);
String jsonArrayPerson = jsonb.toJson(personList);要獲取以下 JSON 格式的表示:
[
{
"email":"[email protected]",
"id":1,
"person-name":"Jhon",
"registeredDate":"09-09-2019",
"salary":"1000.0"
},
{
"email":"[email protected]",
"id":2,
"person-name":"Jhon",
"registeredDate":"09-09-2019",
"salary":"1500.0"
},
...
]要將 JSON 數組轉換為 List,我們將使用 fromJson API。
List<Person> personList = jsonb.fromJson(
personJsonArray,
new ArrayList<Person>(){}.getClass().getGenericSuperclass()
);5.2. 自定義映射與 JsonbConfig
JsonbConfig 類允許我們自定義所有類的映射過程。
例如,我們可以更改默認的命名策略或屬性順序。
現在,我們將使用 LOWER_CASE_WITH_UNDERSCORES 策略:
JsonbConfig config = new JsonbConfig().withPropertyNamingStrategy(
PropertyNamingStrategy.LOWER_CASE_WITH_UNDERSCORES);
Jsonb jsonb = JsonbBuilder.create(config);
String jsonPerson = jsonb.toJson(person);要獲取以下 JSON 格式的表示:
{
"email":"[email protected]",
"id":1,
"person-name":"Jhon",
"registered_date":"07-09-2019",
"salary":"1000.0"
}現在,我們將使用 REVERSE 策略來更改屬性順序。使用此策略,屬性順序與詞典順序相反。
這也可以在編譯時通過註解 @JsonbPropertyOrder 進行配置。讓我們看看它的實際效果:
JsonbConfig config
= new JsonbConfig().withPropertyOrderStrategy(PropertyOrderStrategy.REVERSE);
Jsonb jsonb = JsonbBuilder.create(config);
String jsonPerson = jsonb.toJson(person);
<p>為了獲取以下 JSON 格式的表示:</p>
{
"salary":"1000.0",
"registeredDate":"07-09-2019",
"person-name":"Jhon",
"id":1,
"email":"[email protected]"
}5.3. 自定義映射與適配器
當註解和 <em >JsonbConfig</em> 類不足以滿足我們的需求時,我們可以使用適配器。
要使用它們,我們需要實現 <em >JsonbAdapter</em> 接口,該接口定義了以下方法:
- `adaptToJson` – 通過此方法,我們可以為序列化過程使用自定義轉換邏輯。
- `adaptFromJson` – 此方法允許我們為反序列化過程使用自定義轉換邏輯。
讓我們創建一個 <em >PersonAdapter</em> 以處理 <em >Person</em> 類中的 <em >id</em> 和 <em >name</em> 屬性:
public class PersonAdapter implements JsonbAdapter<Person, JsonObject> {
@Override
public JsonObject adaptToJson(Person p) throws Exception {
return Json.createObjectBuilder()
.add("id", p.getId())
.add("name", p.getName())
.build();
}
@Override
public Person adaptFromJson(JsonObject adapted) throws Exception {
Person person = new Person();
person.setId(adapted.getInt("id"));
person.setName(adapted.getString("name"));
return person;
}
}此外,我們還會將適配器分配到我們的 JsonbConfig 實例上:
JsonbConfig config = new JsonbConfig().withAdapters(new PersonAdapter());
Jsonb jsonb = JsonbBuilder.create(config);我們將會得到以下 JSON 表示:
{
"id":1,
"name":"Jhon"
}6. 結論
在本教程中,我們演示瞭如何使用可用的實現方案,將 JSON-B API 集成到 Java 應用程序中,並提供了自定義編譯時和運行時序列化和反序列化的示例。