学习如何使用Jackson对字段进行序列化并忽略NULL、空和不存在的值。在本教程中,我们将学习不同空值之间的区别以及如何忽略一个特定的值。
1.设置
添加最新版本的Jackson,如果你还没有把它添加到项目中。
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
为了演示的目的,我们将使用以下RecordWithNulls类。我们使用Lombok来减少模板代码,如getters, setters, constructors和*toString()*方法。
@lombok.Data
@lombok.AllArgsConstructor
@lombok.NoArgsConstructor
class RecordWithNulls {
private Long id;
private String text;
private LocalDateTime timestamp;
private Boolean status;
}
2.NULL、空值和缺失值之间的区别
在深入学习代码之前,让我们首先了解空值或缺席值的含义。这样我们就可以更好地决定使用什么选项。
Jackson的枚举JsonInclude.Include ,包含了代表空值或无值的不同数值。
2.1.NULL值
空值是指所有有null 的字段。
2.2.空值
缺少的值包括两种类型。
null值,和- 不存在的 "参考类型的值,如Optional或AtomicReference。例如,在调用Optional.get()方法时,没有值存在。Jackson支持来自Java 8的Optionals,以及Guava。
2.3.空值
空值包括null,不存在,以及一些额外的值。这些包括以下类型。
null空值,以及- 不存在 "的指代类型的值,如Optional或AtomicReference。
- 长度为0的空字符串。
- 空的容器,如大小为0的数组/集合。
为了忽略空值和空值,我们使用*@JsonInclude.Include*枚举中存在的一个值。
JsonInclude.Include.NON_NULLJsonInclude.Include.NON_ABSENTJsonInclude.Include.NON_EMPTY
3.1.在类的层面上
当在类级别上应用@JsonInclude时,所有具有NULL 值的字段在序列化过程中都会被忽略。
@JsonInclude(JsonInclude.Include.NON_NULL)
class RecordWithNulls {
...
}
让我们来测试一下。
RecordWithNulls record = new RecordWithNulls(1L, "test", null, null);
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
String json = mapper.writeValueAsString(record);
上面的代码将产生下面的JSON。
{"id":1,"text":"test"}
3.2.在字段级别
当在字段级应用@JsonInclude时,只有带有NULL 值的注释字段将被忽略。
class RecordWithNulls {
...
@JsonInclude(JsonInclude.Include.NON_NULL)
private LocalDateTime timestamp;
...
}
生成的JSON中,当时间戳字段为NULL时,将被忽略。状态字段将不会被序列化,因为它没有被注释过。
{"id":1,"text":"test","status":null}
4.全局配置ObjectMapper
如果忽略NULL字段是应用程序的默认行为,那么全局配置是有意义的。实现它的一个方法是在ObjectMapper类中进行配置。
ObjectMapper mapper = new ObjectMapper();
...
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
现在这个映射器将忽略它序列化的所有类的所有NULL字段。
5.使用自定义过滤器
我们可以通过创建一个自定义过滤器类并重写其equals() 方法来进一步定制空洞的检查。如果*equals()*返回true 值则被排除(即被过滤掉);如果false 值则被包含。
创建一个像下面这样的自定义过滤器。
class StringFilter {
@Override
public boolean equals(Object value) {
//custom logic
return true;
}
}
并将其注册为一个字段的自定义过滤器,如下所示。
@JsonInclude(value = JsonInclude.Include.CUSTOM, valueFilter = StringFilter.class)
private String text;
5.使用自定义序列器
另一种过滤空值的方法是通过重写自定义序列化器类的isEmpty() 方法。如果isEmpty()返回true,可以使用@JsonInclude(JsonInclude.Include.NON_EMPTY)将字段从序列化中排除。
class RecordSerializer extends StdSerializer<Record> {
...
@Override
public boolean isEmpty(SerializerProvider provider, Record value) {
//write custom logic
//return super.isEmpty(provider, value);
}
...
}
6.结语
在这个简短的教程中,我们学会了在将POJO序列化为JSON时忽略null、 empty和absence值。我们学会了使用@JsonInclude注解和在ObjectMapper类中设置SerializationInclusion功能。