知識庫 / JSON / Jackson RSS 訂閱

lombok 使用的 Jackson 反序列化

Jackson
HongKong
9
09:48 PM · Dec 05 ,2025

1. 概述

通常情況下,在使用 Project Lombok 時,我們常常會希望將我們的數據相關的類與像 Jackson 這樣的 JSON 框架結合使用。 鑑於 JSON 在大多數現代 API 和數據服務中都非常普遍,這一點尤為重要。

在本快速教程中,我們將探討如何配置我們的 Lombok 構建器類,以便它們能夠無縫地與 Jackson 協同工作。

2. 依賴項

我們需要添加的僅僅是 org.projectlombok 到我們的 pom.xml 中:

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.30</version>
</dependency>

當然,我們還需要添加 jackson-databind 依賴項:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.14.1</version>
</dependency>

3. 一個簡單的水果領域

讓我們定義一個啓用了 Lombok 的類,該類包含一個 id 和一個 name,以表示一種水果:

@Data
@Builder
@Jacksonized
public class Fruit {
    private String name;
    private int id;
}

讓我們逐步瞭解我們的POJO的關鍵註釋:

  • 首先,我們為我們的類添加了 @Data 註解——這會生成與簡單的POJO相關的通常樣板代碼,例如getter和setter
  • 然後,我們添加了 @Builder 註解——一種使用Builder模式進行對象創建的有用機制
  • 最後,最重要的是,我們添加了 @Jacksonized 註解

為了簡要説明,@Jacksonized 註解是 @Builder 註解的附加註解。 使用此註解可以自動配置生成的Builder類,使其能夠與Jackson的序列化工作,

請注意,此註解只有在同時存在 @Builder@SuperBuilder 註解時才有效。

最後,我們應該提到,儘管 @Jacksonized 註解是在Lombok v1.18.14中引入的,但它仍然被認為是 實驗性功能

4. 反序列化與序列化

有了我們定義的領域模型,現在讓我們編寫一個單元測試,使用 Jackson 反序列化一個水果:

import org.junit.Test;
import static org.junit.Assert.*;

@Test
public class FruitTest {

    @Test
    public void testDeserializeFruit() {
        // Deserialize a fruit using Jackson
        Fruit fruit = new ObjectMapper().readValue("{\"name\":\"Apple\",\"color\":\"Red\"}", Fruit.class);

        // Assert that the fruit is correctly deserialized
        assertEquals("Apple", fruit.getName());
        assertEquals("Red", fruit.getColor());
    }
}
@Test
public void withFruitJSON_thenDeserializeSucessfully() throws IOException {
    String json = "{\"name\":\"Apple\",\"id\":101}";
        
    Fruit fruit = newObjectMapper().readValue(json, Fruit.class);
    assertEquals(new Fruit("Apple", 101), fruit);
}

簡單的 readValue() API 在 ObjectMapper 中已經足夠了。我們可以使用它將 JSON 格式的水果字符串反序列化為 Fruit Java 對象。

同樣,我們可以使用 writeValue() API 將 Fruit 對象序列化為 JSON 輸出:

@Test
void withFruitObject_thenSerializeSucessfully() throws IOException {
    Fruit fruit = Fruit.builder()
      .id(101)
      .name("Apple")
      .build();

    String json = newObjectMapper().writeValueAsString(fruit);
    assertEquals("{\"name\":\"Apple\",\"id\":101}", json);
}

測試結果展示瞭如何使用 Lombok 構建 Fruit,並且序列化的 Java 對象與預期的 JSON 字符串匹配。

5. 使用自定義構建器

有時,我們可能需要使用自定義構建器實現,而不是Lombok為我們生成的構建器。例如,

讓我們假設我們想要反序列化以下JSON字符串:

{
    "id": 5,
    "name": "Bob"
}

但是,我們 POJO 上的屬性不匹配:

@Data
@Builder(builderClassName = "EmployeeBuilder")
@JsonDeserialize(builder = Employee.EmployeeBuilder.class)
@AllArgsConstructor
public class Employee {

    private int identity;
    private String firstName;

}

在此場景中,我們可以使用 @JsonDeserialize 標註與 @JsonPOJOBuilder 標註結合,將它們插入到生成的構建器類中,以覆蓋 Jackson 的默認設置:

@JsonPOJOBuilder(buildMethodName = "createEmployee", withPrefix = "construct")
public static class EmployeeBuilder {

    private int idValue;
    private String nameValue;

    public EmployeeBuilder constructId(int id) {
        idValue = id;
        return this;
    }
            
    public EmployeeBuilder constructName(String name) {
        nameValue = name;
        return this;
    }

    public Employee createEmployee() {
        return new Employee(idValue, nameValue);
    }
}

然後我們可以按照之前的做法編寫測試代碼:

@Test
public void withEmployeeJSON_thenDeserializeSucessfully() throws IOException {
    String json = "{\"id\":5,\"name\":\"Bob\"}";
    Employee employee = newObjectMapper().readValue(json, Employee.class);

    assertEquals(5, employee.getIdentity());
    assertEquals("Bob", employee.getFirstName());
}

結果顯示,儘管屬性名稱不匹配,一個新的 Employee 數據對象已成功從 JSON 來源重新創建。

6. 結論

在本文中,我們看到了兩種簡單的方法來配置我們的 Lombok 構建器類,使其與 Jackson 無縫協作。

如果沒有 <em @Jacksonized</em> 註解,我們必須專門自定義構建器類。但是,使用 <em @Jacksonized</em> 允許我們使用 Lombok 生成的構建器類。

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

發佈 評論

Some HTML is okay.