美文网首页
Jackson全面解析--注解全讲解二(@JsonAnyGett

Jackson全面解析--注解全讲解二(@JsonAnyGett

作者: 牧羊人刘俏 | 来源:发表于2020-11-24 17:16 被阅读0次

接下来会继续的介绍和使用Jackson里面的剩余的注解

1 @JsonAnyGetter

/**
 * Marker annotation that can be used to define a non-static,
 * no-argument method to be an "any getter"; accessor for getting
 * a set of key/value pairs, to be serialized as part of containing POJO
 * (similar to unwrapping) along with regular property values it has.
 * This typically serves as a counterpart
 * to "any setter" mutators (see {@link JsonAnySetter}).
 * Note that the return type of annotated methods <b>must</b> be
 * {@link java.util.Map}).
 *<p>
 * As with {@link JsonAnySetter}, only one property should be annotated
 * with this annotation; if multiple methods are annotated, an exception
 * may be thrown.
 */
@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotation
public @interface JsonAnyGetter
{
    /**
     * Optional argument that defines whether this annotation is active
     * or not. The only use for value 'false' if for overriding purposes.
     * Overriding may be necessary when used
     * with "mix-in annotations" (aka "annotation overrides").
     * For most cases, however, default value of "true" is just fine
     * and should be omitted.
     *
     * @since 2.9
     */
    boolean enabled() default true;
}

此注解用于序列化操作,由上可以看到,此注解只能用在非静态,且无参数的方法之上,且返回的是一个map,如果将此注解打在此方法上,那么返回的map在序列化的时候就像这个类的普通属性一样(就是解除wrap),此注解很有用,我们还是通过例子来看效果。如下

@NoArgsConstructor
    //@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
    class Agent{

        private String name = "secret";

        @Setter
        private Map<String,String> other = Maps.newHashMap();

        public Map<String,String> getOther(){

            return other;

        }

        
    }

  @Test
    public void  JsonAnyGetterTest() throws Exception{

        CombineJacksonAnnotation.Agent agent = new CombineJacksonAnnotation.Agent();
        agent.getOther().put("att1","att1");

        System.out.println(om.writeValueAsString(agent));


    }
输出的结果如下
{
  "other" : {
    "att1" : "att1"
  }
}

以上,是没有添加JsonAnyGetter的情况,输出的情况,现在我们加上此注解如下

 @JsonAnyGetter
        public Map<String,String> getOther(){

            return other;

        }
输出结果如下
{
  "att1" : "att1"
}

可以看到加上此注解之后,在序列化的时候,other里面的pair对,就像变成了Agent里面的普通属性一样,后面我们会介绍另外一个注解@JsonUnwrapped也能达到相似的效果。

2 @JsonAnySetter

JsonAnySetter用于反序列化时,当对方传过来的json串有识别不了的属性时,可以使用一个map将其全部的接收下来,如下

@NoArgsConstructor
    //@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
    class Agent{

        private String name = "secret";

        @JsonAnySetter
        private Map<String,String> other = Maps.newHashMap();

        @JsonAnyGetter
        public Map<String,String> getOther(){

            return other;

        }


    }

 @Test
    public void JsonAnySetterTest() throws Exception{

        CombineJacksonAnnotation.Agent agent  = om.readValue("{\n" +
                "  \"name\" : \"tom\",\n" +
                "  \"age\" : 12,\n" +
                "  \"sex\" : \"female\"\n" +
                "}",CombineJacksonAnnotation.Agent.class);

        System.out.println(om.writeValueAsString(agent));


    }

结果如下


image.png

可以看到other里面接收了所有Agent里面识别不了的属性。
大家可能看到,Agent里面不是有一个name吗,为什么没有被覆盖呢,那是因为这个name的属性是private的,反序列化器接触不到,我们下个注解可以解决这个问题。

3 @JsonAutoDetect

我们还是针对上面的反序列化问题进行,验证,将此注解打在Agent上面,修改如下

  @NoArgsConstructor
    @JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
    class Agent{

        private String name = "secret";

        @JsonAnySetter
        private Map<String,String> other = Maps.newHashMap();

        @JsonAnyGetter
        public Map<String,String> getOther(){

            return other;

        }

    }

运行结果如下


image.png

可以看到name被成功的被反序列化成了tom,为什么会这样呢,因为
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
加上这个注解,表明所有的filed字段都是可见的,不管是何种可见级别(jackson会使用反射去获取),一般如果代码规范到位,其实我觉得是用不上这个注解的,

   /**
     * Minimum visibility required for auto-detecting regular getter methods.
     */
    Visibility getterVisibility() default Visibility.DEFAULT;

    /**
     * Minimum visibility required for auto-detecting is-getter methods.
     */
    Visibility isGetterVisibility() default Visibility.DEFAULT;
    
    /**
     * Minimum visibility required for auto-detecting setter methods.
     */    
    Visibility setterVisibility() default Visibility.DEFAULT;

    /**
     * Minimum visibility required for auto-detecting Creator methods,
     * except for no-argument constructors (which are always detected
     * no matter what).
     */
    Visibility creatorVisibility() default Visibility.DEFAULT;

    /**
     * Minimum visibility required for auto-detecting member fields.
     */ 
    Visibility fieldVisibility() default Visibility.DEFAULT;

JsonAutoDetect定义了5个属性用来分别控制,getter、isGetter、 setter、creator、field的可见级别。

相关文章

网友评论

      本文标题:Jackson全面解析--注解全讲解二(@JsonAnyGett

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