java:jackson 四:Jackson Property Inclusion Annotations
1 前言
参考文档地址:
https://www.baeldung.com/jackson
https://www.baeldung.com/jackson-annotations
SpringBoot自带的jackson版本如下:
<parent>
<artifactId>spring-boot-starter-parent</artifactId>
<groupId>org.springframework.boot</groupId>
<version>2.5.4</version>
</parent>
或者不使用SpringBoot情况下,单独配置jackson-databind版本:
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<jackson-databind.version>2.14.1</jackson-databind.version>
</properties>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson-databind.version}</version>
</dependency>
同时使用SpringBoot和自定义的jackson版本时,注意避免依赖冲突。
2 使用
2.1 @JsonIgnoreProperties
@JsonIgnoreProperties is a class-level annotation that marks a property or a list of properties that Jackson will ignore.
因此@JsonIgnoreProperties在类上使用时,可以忽略字段:
如下序列化时,必须有对应的Getter方法:
@JsonIgnoreProperties(value = {"id","value"})
@AllArgsConstructor
@Getter
class JacksonVO {
int id;
String fruitName;
int age;
String value;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
Date day;
@Override
public String toString(){
return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
}
}
JacksonVO jacksonVO = new JacksonVO(1,"apple", 22, "nihao", new Date());
System.out.println(jacksonVO);
System.out.println(objectMapper.writeValueAsString(jacksonVO));
执行结果:
JacksonVO[age=22,day=Thu Dec 29 16:40:49 CST 2022,fruitName=apple,id=1,value=nihao]
{
"fruitName" : "apple",
"age" : 22,
"day" : "2022-12-29 16:40:49"
}
2.2 @JsonIgnore
In contrast, the @JsonIgnore annotation is used to mark a property to be ignored at the field level.
可见,@JsonIgnore使用于Field上的,如下:
@JsonIgnoreProperties(value = {"id","value"})
@AllArgsConstructor
@Getter
class JacksonVO {
int id;
String fruitName;
@JsonIgnore
int age;
String value;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
Date day;
@Override
public String toString(){
return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
}
}
JacksonVO jacksonVO = new JacksonVO(1,"apple", 22, "nihao", new Date());
System.out.println(jacksonVO);
System.out.println(objectMapper.writeValueAsString(jacksonVO));
执行结果:
JacksonVO[age=22,day=Thu Dec 29 16:51:40 CST 2022,fruitName=apple,id=1,value=nihao]
{
"fruitName" : "apple",
"day" : "2022-12-29 16:51:40"
}
2.3 @JsonIgnoreType
@JsonIgnoreType marks all properties of an annotated type to be ignored.
We can use the annotation to mark all properties of type Name to be ignored:
@Getter
@Setter
@AllArgsConstructor
class JacksonVO1 {
int id;
JacksonVO2 vo2;
@JsonIgnoreType
@Getter
@Setter
@AllArgsConstructor
static class JacksonVO2{
int jid;
String name;
@Override
public String toString(){
return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
}
}
@Override
public String toString(){
return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
}
}
JacksonVO1 jacksonVO = new JacksonVO1(1,new JacksonVO1.JacksonVO2(123,"xiaoxu"));
System.out.println(jacksonVO);
System.out.println(objectMapper.writeValueAsString(jacksonVO));
执行结果:
JacksonVO1[id=1,vo2=JacksonVO1.JacksonVO2[jid=123,name=xiaoxu]]
{
"id" : 1
}
2.4 @JsonInclude
We can use @JsonInclude to exclude properties with empty/null/default values.
Let’s look at an example excluding nulls from serialization:
@Getter
@JsonInclude(JsonInclude.Include.NON_NULL)
@AllArgsConstructor
class JacksonVO2 {
int id;
String name;
Boolean flag;
String value;
@Override
public String toString(){
return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
}
}
JacksonVO2 jacksonVO = new JacksonVO2(1, "xiaoxu", null, null);
System.out.println(jacksonVO);
System.out.println(objectMapper.writeValueAsString(jacksonVO));
执行结果:
JacksonVO2[flag=<null>,id=1,name=xiaoxu,value=<null>]
{
"id" : 1,
"name" : "xiaoxu"
}
@JsonInclude除了作用在类上,亦可作用在Field上:
修改DTO:
@Getter
@AllArgsConstructor
class JacksonVO2 {
int id;
String name;
@JsonInclude(JsonInclude.Include.NON_NULL)
Boolean flag;
String value;
@Override
public String toString(){
return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
}
}
再次执行:
JacksonVO2[flag=<null>,id=1,name=xiaoxu,value=<null>]
{
"id" : 1,
"name" : "xiaoxu",
"value" : null
}
2.5 @JsonAutoDetect
@JsonAutoDetect can override the default semantics of which properties are visible and which are not.
First, let’s take a look at how the annotation can be very helpful with a simple example; let’s enable serializing private properties.
DTO含有private字段:
@Getter
@AllArgsConstructor
@JsonAutoDetect
class JacksonVO3 {
private int id;
private String name;
private Boolean flag;
String value;
@Override
public String toString(){
return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
}
}
JacksonVO3 jacksonVO =new JacksonVO3(1, "xiaoxu", Boolean.TRUE, "value1");
System.out.println(jacksonVO);
System.out.println(objectMapper.writeValueAsString(jacksonVO));
执行结果:
JacksonVO3[flag=true,id=1,name=xiaoxu,value=value1]
{
"id" : 1,
"name" : "xiaoxu",
"flag" : true,
"value" : "value1"
}
2.6 @JsonFilter
The @JsonFilter annotation specifies a filter to use during serialization.
First, we define the entity and we point to the filter.
Now in the full test, we define the filter, which excludes all other properties except name from serialization.
如果需要根据场景自定义字段是否展示(比如A场景不展示这个字段,但是B场景需要展示这个字段,如果固定配置为@JsonIgnore,或者@JsonIgnoreProperties(value = {“id”,“value”}),反而不够灵活),此时可考虑@JsonFilter注解(自定义Filter,实现自定义序列化展示,根据场景选择是否需要使用该filter即可)
@Getter
@AllArgsConstructor
@JsonAutoDetect
@JsonFilter(value = "xiaoxuFilter")
class JacksonVO3 {
private int id;
private String name;
private Boolean flag;
String value;
@Override
public String toString(){
return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
}
}
/* 序列化时,仅保留 "id","name","flag" 三个字段 */
FilterProvider filter = new SimpleFilterProvider()
.addFilter("xiaoxuFilter",
SimpleBeanPropertyFilter.filterOutAllExcept("id","name","flag"));
JacksonVO3 jacksonVO = new JacksonVO3(1, "xiaoxu", Boolean.TRUE, "value1");
System.out.println(jacksonVO);
System.out.println(objectMapper.writer(filter).writeValueAsString(jacksonVO));
执行结果:
JacksonVO3[flag=true,id=1,name=xiaoxu,value=value1]
{
"id" : 1,
"name" : "xiaoxu",
"flag" : true
}
使用另外的filter,更灵活:
/* 序列化时,仅保留 "id","name","flag" 三个字段 */
FilterProvider filter = new SimpleFilterProvider()
.addFilter("xiaoxuFilter",
SimpleBeanPropertyFilter.filterOutAllExcept("id","name","flag"));
/* 序列化时,除了"id","name"不展示,其余均展示 */
SimpleBeanPropertyFilter filter1 = SimpleBeanPropertyFilter
.serializeAllExcept("id","name");
FilterProvider filter2 = new SimpleFilterProvider()
.addFilter("xiaoxuFilter",filter1);
JacksonVO3 jacksonVO = new JacksonVO3(1, "xiaoxu", Boolean.TRUE, "value1");
System.out.println(jacksonVO);
System.out.println(objectMapper.writer(filter2).writeValueAsString(jacksonVO));
执行结果:
JacksonVO3[flag=true,id=1,name=xiaoxu,value=value1]
{
"flag" : true,
"value" : "value1"
}