本文将介绍Jackson一些常见、常用的注解,也会介绍一些少见但很有用的注解。
先说说序列化相关的注解。
JsonAnyGetter一般的实体定义中,我们一定会用基本数据来定义属性,比如int、String等,然后会给它们指定相应的属性名字,名字即对应于json中的key。但有时我们想偷懒,不想写这么多名字,我们则可以定义一个Map。这种情况下,我样可以给这个Map增加一个注解,即
JsonAnyGetter。有了这个注解,Jackson就会自动帮我们把Map的key和value映射为json的key和value。
示例代码如下:
publicclassExtendableBean{publicStringname;privateMapString,Stringproperties;
JsonAnyGetterpublicMapString,StringgetProperties(){returnproperties;}}生成的json示例:
{"name":"Mybean","attr2":"val2","attr1":"val1"}
JsonGetterJsonGetter我们一般用得不多,更多是直接使用JsonProperty。使用JsonGetter的话,是表明该方法为对应属性的Getter,主要用于非标准的Getter命名。示例代码如下:
publicclassMyBean{publicintid;privateStringname;
JsonGetter("name")publicStringgetTheName(){returnname;}}JsonPropertyOrderJsonPropertyOrder用于指定实体生成json时的属性顺序,一般用得不多,但对于某些特殊场景,或强迫症人士,很有用。示例代码如下:
JsonPropertyOrder({"name","id"})publicclassMyBean{publicintid;publicStringname;}生成的json示例:
{"name":"Mybean","id":1}
JsonRawValueJsonRawValue适用于把json串直接作为实体属性时,又想它这个json串的属性与当前实体合成一个完整json。这种场景一般适合传递的数据中又包含字符串,而字符串又是json。示例代码如下:
publicclassRawBean{publicStringname;
JsonRawValuepublicStringjson;}生成的json示例:
{"name":"Mybean","json":{"attr":false}}
JsonValueJsonValue是一个比较常用的注解,可以用于指定使用哪个方法来序列化整个实体,特别适合枚举类型。示例代码如下:
publicenumTypeEnumWithValue{TYPE1(1,"TypeA"),TYPE2(2,"Type2");privateIntegerid;privateStringname;//standardconstructors
JsonValuepublicStringgetName(){returnname;}}如果我们某个实体中使用了此枚举,序列化出来的json串使用的将是该枚举的name。
JsonRootNameJsonRootName是一个很有用,但很多人不知道的注解。有些时候,我们的json需要包装一个根名字,我们常常得再定义一个实体的包装类,有了这个注解就不用再定论包装类了。示例代码如下:
JsonRootName(value="user")publicclassUserWithRoot{publicintid;publicStringname;}生成的json如下:
{"User":{"id":1,"name":"John"}}
JsonSerializeJsonSerialize用于解决特殊数据的序列化问题,一般我们用于解决枚举和日期属性序列化成什么格式的问题。比如,对一个日期属性,我们有自己的格式需求,我们就可以自定义一个序列化类,然后将它绑定给对应的属性。示例代码如下:
publicclassEventWithSerializer{
publicStringname;
JsonSerialize(using=CustomDateSerializer.class)publicDateeventDate;
}
自定义序列化类,示例代码如下:
publicclassCustomDateSerializerextendsStdSerializerDate{privatestaticSimpleDateFormatformatter=newSimpleDateFormat("dd-MM-yyyyhh:mm:ss");publicCustomDateSerializer(){this(null);}publicCustomDateSerializer(ClassDatet){super(t);}
Overridepublicvoidserialize(Datevalue,JsonGeneratorgen,SerializerProviderarg2)throwsIOException,JsonProcessingException{gen.writeString(formatter.format(value));}}通过以上配置后,Jackson就会按我们自定义格式输出日期。
再说说反序列化的注解。
JsonCreator当我们获得的json串和对应的实体类属性存在差异时,我们想要粘合二者,只需要通过
JsonCreator来定义构造函数中属性如何指定即可。示例json如下:
{"id":1,"theName":"Mybean"}
对应的实体类代码如下:
publicclassBeanWithCreator{publicintid;publicStringname;
JsonCreatorpublicBeanWithCreator(JsonProperty("id")intid,JsonProperty("theName")Stringname){this.id=id;this.name=name;}}以上代码中,jackson将把会json串中的theName转换到实体的name属性中。
JsonAnySetterJsonAnySetter对应于JsonAnyGetter,将json属性反序列化到一个Map中。示例json如下:
{"name":"Mybean","attr2":"val2","attr1":"val1"}
示例实体类定义如下:
publicclassExtendableBean{publicStringname;privateMapString,Stringproperties;
JsonAnySetterpublicvoidadd(Stringkey,Stringvalue){properties.put(key,value);}}转换为实体后,attr2和attr1将会转换到Map中。
JsonSetterJsonSetter对应于JsonGetter,用于指定json属性对应于实体的哪个属性,主要用于Setter名字非标准的情况。示例代码如下:
publicclassMyBean{publicintid;privateStringname;
JsonSetter("name")publicvoidsetTheName(Stringname){this.name=name;}}JsonDeserializeJsonDeserialize对应于JsonSerialize,用于解决json按什么格式映射到实体属性的问题。示例代码如下:
publicclassEventWithSerializer{publicStringname;
JsonDeserialize(using=CustomDateDeserializer.class)publicDateeventDate;}以上代码中自定义了一个反序列化实现,自定义反序列化类代码如下:
publicclassCustomDateDeserializerextendsStdDeserializerDate{privatestaticSimpleDateFormatformatter=newSimpleDateFormat("dd-MM-yyyyhh:mm:ss");publicCustomDateDeserializer(){this(null);}publicCustomDateDeserializer(Class?vc){super(vc);}
OverridepublicDatedeserialize(JsonParserjsonparser,DeserializationContextcontext)throwsIOException{Stringdate=jsonparser.getText();try{returnformatter.parse(date);}catch(ParseExceptione){thrownewRuntimeException(e);}}}通过以上自定义的反序列化类,将json中的日期字符串转为相应的日期属性。
JsonAliasJsonAlias一个用得不多的注解,它能给实体属性定义多个对应的json的key,但这种情况实在很少,真有的话,这个注解挺有用的。示例代码如下:
publicclassAliasBean{
JsonAlias({"fName","f_name"})privateStringfirstName;privateStringlastName;}以上定义中,不论json中是firstName,还是fName,还是f_name,都会遇到属性firstName上。
除了序列和反序列化,还有一些很有用的注解。
JsonIgnoreProperties如果我们要忽略实体中一的些属性,不让它们参与json的序列化和反序列化,那么
JsonIgnoreProperties就派上用场了。示例代码如下:
JsonIgnoreProperties({"id"})publicclassBeanWithIgnore{publicintid;publicStringname;}JsonIgnore类似于
JsonIgnoreProperties的排除属性,区别只在于JsonIgnore是在属性是声明。示例代码如下:
publicclassBeanWithIgnore{
JsonIgnorepublicintid;publicStringname;}JsonIncludeJsonInclude主要用于条件化的排除属性参与json序列化和反序列化。比如当属性值为null时,我们在json中不想看到它,那这个注解就非常有用。示例代码如下:
JsonInclude(Include.NON_NULL)publicclassMyBean{publicintid;publicStringname;}或
publicclassMyBean{publicintid;
JsonInclude(Include.NON_NULL)publicStringname;}以上就是一些常见或者不常见,但都挺好用的注解,还有一些比较冷门的注解就不再介绍,有需要可以自行看官方文档学习。