美文网首页
Jackson全面解析--注解全讲解七(@JsonGetter

Jackson全面解析--注解全讲解七(@JsonGetter

作者: 牧羊人刘俏 | 来源:发表于2020-12-01 19:35 被阅读0次

这一对注解用于序列化和反序列化,我们先看

@JsonGetter

先看个简单的例子,如下

 @AllArgsConstructor(staticName = "of")
    @NoArgsConstructor
    class  Pojo{

        @Getter
        @Setter //后面源码分析的时候要把这个地方看下,什么样的方法会被序列化
        private String att1;

        public String getTheAtt2(){

            return "anyNull";
        }

    }
运行测试代码
  @Test
    public void JsonGetterTest() throws Exception{

        CombineJacksonAnnotation.Pojo pojo = CombineJacksonAnnotation.Pojo.of("att1");
        System.out.println(om.writeValueAsString(pojo));

    }
结果如下
{
  "att1" : "att1",
  "theAtt2" : "anyNull"
}

可以看到
getTheAtt2()方法也被序列化了,按照驼峰命名规则去掉get剩下的就是默认的序列化之后的生成的属性名,而@JsonGetter的作用就是给这个被序列化的方法命名一个逻辑的属性名,如下,我们修改下代码

@AllArgsConstructor(staticName = "of")
    @NoArgsConstructor
    class  Pojo{

        @Getter
        @Setter //后面源码分析的时候要把这个地方看下,什么样的方法会被序列化
        private String att1;
        
        @JsonGetter("att2")
        public String getTheAtt2(){

            return "anyNull";
        }

    }
再运行测试代码,返回如下
{
  "att1" : "att1",
  "att2" : "anyNull"
}

可以看到getTheAtt2()序列化后的属性名变成了att2,这就是@JsonGetter的作用。
我们可以继续的看下@JsonGetter的详细作用。

/**
 * Marker annotation that can be used to define a non-static,
 * no-argument value-returning (non-void) method to be used as a "getter"
 * for a logical property.
 * It can be used as an alternative to more general
 * {@link JsonProperty} annotation (which is the recommended choice in
 * general case).
 *<p>
 * Getter means that when serializing Object instance of class that has
 * this method (possibly inherited from a super class), a call is made
 * through the method, and return value will be serialized as value of
 * the property.
 */
注释写的很清楚,用于一个无参的非静态的有一个返回值的方法,但是这个注解可以用@JsonProperty同样来实现,我们点到源码里面看下

JacksonAnnotationIntrospector.class
 @Override
    public PropertyName findNameForSerialization(Annotated a)
    {
        boolean useDefault = false;
        JsonGetter jg = _findAnnotation(a, JsonGetter.class);
        if (jg != null) {
            String s = jg.value();
            // 04-May-2018, tatu: Should allow for "nameless" `@JsonGetter` too
            if (!s.isEmpty()) {
                return PropertyName.construct(s);
            }
            useDefault = true;
        }
        JsonProperty pann = _findAnnotation(a, JsonProperty.class);
        if (pann != null) {
            return PropertyName.construct(pann.value());
        }
        if (useDefault || _hasOneOf(a, ANNOTATIONS_TO_INFER_SER)) {
            return PropertyName.USE_DEFAULT;
        }
        return null;
    }

可以看到@JsonGetter比@JsonProperty的优先级高,我们试验下,改下代码,如下

 @AllArgsConstructor(staticName = "of")
    @NoArgsConstructor
    class  Pojo{

        @Getter
        @Setter //后面源码分析的时候要把这个地方看下,什么样的方法会被序列化
        private String att1;

        @JsonGetter("att2")
        @JsonProperty("att3")
        public String getTheAtt2(){

            return "anyNull";
        }

    }
返回结果没变
{
  "att1" : "att1",
  "att2" : "anyNull"
}

再次修改代码,如下
 @AllArgsConstructor(staticName = "of")
    @NoArgsConstructor
    class  Pojo{

        @Getter
        @Setter //后面源码分析的时候要把这个地方看下,什么样的方法会被序列化
        private String att1;

        @JsonProperty("att3")
        public String getTheAtt2(){

            return "anyNull";
        }

    }
返回结果变了
{
  "att1" : "att1",
  "att3" : "anyNull"
}

那如果我们修改成如下,如果方法序列化后的属性名与已存在的属性名重复会怎么样呢

 @AllArgsConstructor(staticName = "of")
    @NoArgsConstructor
    class  Pojo{

        @Getter
        @Setter //后面源码分析的时候要把这个地方看下,什么样的方法会被序列化
        private String att1;

        @JsonGetter("att1")
        public String getTheAtt2(){

            return "anyNull";
        }

    }
返回如下
{
  "att1" : "anyNull"
}

上面的这点很重要,如果用的不好,可能发现序列化的结果不满足要求了。

@JsonSetter

既然@JsonGetter用于序列化,那么@JsonSetter就是用于反序列化了,
指定的method会去修改指定的属性。使用方法如下

 @AllArgsConstructor(staticName = "of")
    @NoArgsConstructor
    class  Pojo{

        @Getter
        @Setter //后面源码分析的时候要把这个地方看下,什么样的方法会被序列化
        private String att1;



        @JsonSetter(value = "att2")
        public void setTheXxx(String xxx){

            this.att1 = xxx;

        }

    }

上面的意思是说,解析出来的att2,然后将其值赋值给了att1,


image.png

所以反序列化出来就是上面的结果。

可以认为Jackson是按照标准的setter和getter来反序列化和序列化对象的,如果不是标准的方法,可以使用@JsonGetter @JsonSetter来转义。

相关文章

网友评论

      本文标题:Jackson全面解析--注解全讲解七(@JsonGetter

      本文链接:https://www.haomeiwen.com/subject/yzoswktx.html