知識庫 / JSON RSS 訂閱

JSON 綁定 API (JSR 367) 在 Java 中的介紹

Jakarta EE,JSON
HongKong
5
09:55 PM · Dec 05 ,2025

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 應用程序中,並提供了自定義編譯時和運行時序列化和反序列化的示例。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.