目录
前言:
@JsonInclude注解是Jackson中最常用的注解之一,是实体类在接口序列化返回值时所使用规则的注解。比如说我们在开发过程中,返回前端的实体类中如果某个字段为空或者特定值的话,那么就不返回这个字段了。这种场景下,@JsonInclude就是用来解决这个问题。在实体类序列化成Json时在某些策略下,加了该注解的字段不去序列化该字段。
使用:
ALWAYS // 默认策略,任何情况都执行序列化
NON_NULL // 非空
NON_ABSENT // null的不会序列化,但如果类型是AtomicReference,依然会被序列化
NON_EMPTY // null、集合数组等没有内容、空字符串等,都不会被序列化
NON_DEFAULT // 如果字段是默认值,就不会被序列化
CUSTOM // 此时要指定valueFilter属性,该属性对应一个类,用来自定义判断被JsonInclude修饰的字段是否序列化
USE_DEFAULTS // 当JsonInclude在类和属性上都有时,优先使用属性上的注解,此时如果在序列化的get方法上使用了JsonInclude,并设置为USE_DEFAULTS,就会使用类注解的设置
1、ALWAYS
表示总是全部序列化,null值和空值也会全部进行序列化返回
代码:
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
import lombok.Data;
public class Always {
@Data
@JsonInclude(JsonInclude.Include.ALWAYS)
static class AlwaysTest{
private String id;
private String username;
private String password;
}
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
//美化输出
mapper.enable(SerializationFeature.INDENT_OUTPUT);
//jackson支持Optional特性
mapper.registerModule(new Jdk8Module());
AlwaysTest test = new AlwaysTest();
test.setId("123");
test.setUsername("");
test.setPassword(null);
System.out.println(mapper.writeValueAsString(test));
}
}
结果:
{
"id" : "123",
"username" : "",
"password" : null
}
2、NON_NULL
NON_NULL表示没有null值,如果值为null就不进行序列化
代码:
public class NonNull {
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
static class NonNullTest{
private String id;
private String username;
private String password;
}
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
//美化输出
mapper.enable(SerializationFeature.INDENT_OUTPUT);
//jackson支持Optional特性
mapper.registerModule(new Jdk8Module());
NonNullTest test = new NonNullTest();
test.setId("123");
test.setUsername("");
test.setPassword(null);
System.out.println(mapper.writeValueAsString(test));
}
}
结果:
{
"id" : "123",
"username" : ""
}
3、NON_ABSENT
1)NON_ABSENT略为复杂,当实例化的对象有Optional或AtomicReference类型的成员变量时,如果Optional引用的实例为空,用NON_ABSENT能使该字段不做序列化;
2)Optional是java用来优雅处理空指针的一个特性,本文中不做过多说明,请您自行查阅相关文档;
3)当有属性值为null时,也不会对其进行序列化
4)要让Jackson支持Optional特性,必须做两件事,首先是在pom.xml中添加以下依赖:
依赖:
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jdk8</artifactId>
<version>2.11.0</version>
</dependency>
设置:
mapper.registerModule(new Jdk8Module());
代码:
public class NonAbsent {
@Data
@JsonInclude(value = JsonInclude.Include.NON_ABSENT)
static class NonAbsentTest{
private String id;
private String username;
private String password;
private int age;
private Optional<String> filed1;
private AtomicReference<String> filed2;
}
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
//美化输出
mapper.enable(SerializationFeature.INDENT_OUTPUT);
//jackson支持Optional特性
mapper.registerModule(new Jdk8Module());
NonAbsentTest test = new NonAbsentTest();
test.setId("123");
test.setUsername("");
test.setPassword(null);
test.setAge(0);
test.setFiled1(Optional.empty());
test.setFiled2(new AtomicReference<>());
System.out.println(mapper.writeValueAsString(test));
}
}
结果:
{
"id" : "123",
"username" : "",
"age" : 0
}
4、NON_EMPTY
NON_EMPTY在以下情况都不会被序列化:
1)null值
2)空字符串
3)空集合
4)空数组
5)Optional类型的,其引用为空
6)AtomicReference类型的,其引用为空
代码:
public class NonEmpty {
@Data
@JsonInclude(value = JsonInclude.Include.NON_EMPTY)
static class NonEmptyTest{
private String id;
private String username;
private String password;
private Optional<String> filed1;
private AtomicReference<String> filed2;
private List<String> filed3;
}
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
//美化输出
mapper.enable(SerializationFeature.INDENT_OUTPUT);
//jackson支持Optional特性
//字段设置为null、空字符串、空集合、引用
mapper.registerModule(new Jdk8Module());
NonEmptyTest test = new NonEmptyTest();
test.setId("");
test.setUsername("");
test.setPassword(null);
test.setFiled1(Optional.empty());
test.setFiled2(new AtomicReference<>());
test.setFiled3(new ArrayList<>());
System.out.println(mapper.writeValueAsString(test));
}
}
结果:
{ }
5、NON_DEFAULT
NON_DEFAULT对保持默认值和null值的字段不做序列化
代码:
public class NonDefault {
@Data
@JsonInclude(JsonInclude.Include.NON_DEFAULT)
static class NonDefaultTest{
private String id;
private String username = "admin";
private String password = "123456";
}
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
//美化输出
mapper.enable(SerializationFeature.INDENT_OUTPUT);
//jackson支持Optional特性
mapper.registerModule(new Jdk8Module());
//password使用默认值 username使用新值
NonDefaultTest test = new NonDefaultTest();
test.setUsername("root");
test.setId(null);
System.out.println(mapper.writeValueAsString(test));
}
}
结果:
{
"username" : "root"
}
6、CUSTOM
1)相对其他类型,CUSTOM略为复杂,这个值要配合valueFilter放在属性上一起使用;
20如下所示,JsonInclude的value等于CUSTOM时,在序列化的时候会执行CustomFilter的equals方法,该方法的入参就是field0的值,如果equals方法返回true,field0就不会被序列化,如果equals方法返回false时field0才会被序列化
代码:
public class Custom {
@Data
@JsonInclude(value = JsonInclude.Include.CUSTOM,valueFilter = ValueFilter.class)
static class CustomTest{
private String id;
private String username;
private String password;
private int age;
}
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
//美化输出
mapper.enable(SerializationFeature.INDENT_OUTPUT);
//jackson支持Optional特性
mapper.registerModule(new Jdk8Module());
CustomTest test = new CustomTest();
test.setId("123");
test.setUsername("");
test.setPassword(null);
test.setAge(0);
System.out.println(mapper.writeValueAsString(test));
}
}
public class ValueFilter {
//返回true时 不进行序列化
@Override
public boolean equals(Object obj) {
if (obj == null || obj.equals("") || obj.equals(0)) {
return true;
}
return false;
}
}
结果:
{
"id" : "123"
}