使用@JsonProperty注解会多出一个字段的原因

现象:

将一个java对象返回给前端时,个别的属性无法正常显示,比如类似DD这种全大写的属性,返回给前端就会变成dd,springboot默认使用的jackson组件,我们可以使用@JsonProperty("DD")注解进行调整,如果将注解写在属性上(比如使用Lombok组件时,没有get/set方法),就可能会出现返给前端多一个属性的问题,dd、DD都给前端返回了。

public class TestJackson {

    @JsonProperty("DD")
    private String DD;

    private String alpha;

    private String beta;

//    get/set 方法 省略 未列出
}
复制代码

引用一句网上摘抄的话

以下是引用的原文: jackson2对pojo类型序列化的处理。

Jackson2在初始化序列器时,对pojo类型对象会收集其属性信息,属性包括成员变量及方法,然后属性名称和处理过后的方法名称做为key保存到一个LinkedHashMap中。收集过程中会调用com.fasterxml.jackson.databind.util.BeanUtil中的legacyManglePropertyName方法用来处理方法名称,它会将get/set方法前缀,即get或set去掉,并将其后面的连续大写字符转换成小写字符返回。例如: getNEWString会转变成newstring返回。你的属性名称如果有这样的"nSmallSellCount",lombok自动生成的get方法就会是这样的"getNSmallSellCount",处理过后就是这样的"nsmallSellCount",这与属性nSmallSellCount并不冲突,可以同时存在于HashMap中。收集完属性信息后,下面的步骤中会删除掉非可见的属性,一般指的是私有成员变量,这时,名称为"nSmallSellCount"的成员变量属性会被删除掉,这样的序列化结果是不会有问题的,但,如果加了@JsonProperty注释,Jackson2会认为这个属性是可见的,不必会删除,这时这两个表示同一个值得属性就会被一同序列化。

用jackson的@JsonProperty注解属性名,会多出一个字段:用jackson的@JsonProperty注解属性名,会多出一个字段_rumeng_you_51CTO博客

以上面的内容为依据,并且根据自己的测试,发现了以下的规律

1、在没有@JsonProperty的情况下,私有属性默认是不可见的,若存在get方法,可以根据get方法得到字段,值也是get方法的值

2、如果没有属性,只有get方法也是可以得到字段的。特殊的属性,比如DD,这种生成的get方法是getDD,getDD得到的字段是dd。这里就可以简单理解为getDD是没有属性的get方法,DD是独立的私有属性,这样也能解释为什么返给前端的是dd,而不是DD

3、如果属性是公有的,那么没有get方法也可以得到字段,这时字段的值就是属性的值

4、私有属性加了注解会变得可见

5、默认字段的顺序:没有@JsonProperty注解(属性、get/set方法都没有注解)的属性(公有属性或有get方法),没有注解且独立的get方法(没有属性),有注解的属性,有注解的独立get方法

所以出现多字段的原因就可以解释为,首先DD与getDD是不关联的两个个体,getDD可以得到dd字段,给DD属性加上@JsonProperty("DD")注解后变得可见,得到DD字段,但是DD与dd没有直接关系,所以就都出现了

可能会出现的异常显示现象

1、字段的值不是属性的值:有get方法但是get方法返回的值不是属性的值

2、出现一些不是属性的字段:写了get方法但是没有对应到某个属性,因为会根据get方法得到字段

使用@JsonProperty注解多出一个字段的解决办法:

根据以上规律,还是在get方法加注解是比较合适的,如果使用Lombok最好重写下get方法,保持私有属性不可见

public class TestJackson {

    private String DD;

    private String alpha;

    private String beta;

    public TestJackson() {
    }

    @JsonProperty("DD")
    public String getDD() {
        return DD;
    }

    public void setDD(String DD) {
        this.DD = DD;
    }

//    其它 get/set 方法 省略 未列出
}
复制代码

猜你喜欢

转载自juejin.im/post/7096862201327124488