概述
在使用Project Lombok时,我们常常希望将数据相关类与像Jackson这样的JSON框架结合。特别是在现代API和数据服务中,JSON的广泛应用使得这种需求尤为明显。
在这篇快速教程中,我们将探讨如何配置Lombok的构建器类,使其与Jackson无缝集成。
依赖项
我们首先需要在pom.xml
中添加Lombok库的依赖:
<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>
一个简单的水果领域模型
让我们定义一个启用Lombok的类,包含一个id和一个name,表示一种水果:
@Data
@Builder
@Jacksonized
public class Fruit {
private String name;
private int id;
}
接下来,我们逐步解释POJO的关键注解:
- 首先,我们在类上添加
@Data
注解,这会生成通常与简单POJO关联的模板代码,如getter和setter方法。 - 然后,我们添加
@Builder
注解——这是一个有用的机制,使用构建器模式创建对象。 - 最重要的是,我们添加
@Jacksonized
注解。
简而言之,@Jacksonized
是@Builder
的附加注解。使用这个注解可以自动配置生成的构建器类以与Jackson的反序列化功能协同工作。
需要注意的是,只有当存在@Builder
或@SuperBuilder
注解时,@Jacksonized
注解才会生效。
最后,虽然@Jacksonized
在Lombok v1.18.14版本中引入,但它仍然被视为一个实验性特性。
4. 反序列化和序列化
现在我们的领域模型已经定义好,让我们编写一个单元测试,使用Jackson反序列化一个水果:
@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);
}
ObjectMapper
的简单readValue()
方法就足够了。我们可以使用它将JSON水果字符串反序列化为一个Fruit
Java对象。
同样地,我们可以使用writeValue()
方法将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构建器API构建Fruit
,并且序列化的Java对象与预期的JSON字符串匹配。
5. 与自定义构建器协作
有时我们需要使用自定义的构建器实现,而不是Lombok为我们生成的。例如,当我们的bean属性名称与JSON字符串中的字段名称不匹配时。
假设我们想要反序列化以下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());
}
结果显示,尽管属性名称不匹配,但仍成功从JSON源创建了一个新的Employee
数据对象。
6. 总结
在这篇短文中,我们了解了两种简单的方法来配置Lombok的构建器类与Jackson无缝集成。
如果没有@Jacksonized
注解,我们将不得不特别定制我们的构建器类。然而,使用@Jacksonized
,我们可以利用Lombok生成的构建器类。
如往常一样,本文的完整源代码可在GitHub上获取。