java:jackson 四:Jackson Property Inclusion Annotations

本文介绍了Jackson库中用于控制JSON序列化行为的各种注解,包括@JsonIgnoreProperties、@JsonIgnore、@JsonIgnoreType、@JsonInclude、@JsonAutoDetect和@JsonFilter等,并提供了详细的示例说明。

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"
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值