Hi,我们好,我是抢老婆酸奶的小肥仔。
咱们日常开发中,经常会用到json数据格式。在java中运用json也有许多工具包,例如:google的gson,阿里的fastjson,jdk自带的json,及咱们今日要说的jackson,各工具包有各自的优点。咱们今日就来说说jackson,在咱们日常工作中会给咱们带来事半功倍的效果。
1、Jackson简介
jackson是一个简单且功能强大的基于java的运用库,它能够快捷的完结Java目标和Json目标的转化。其具有以下特性:
- 高性能且安稳:Jackson低内存占用,对Json和目标的解析都很优秀
- 盛行度高:Jackson的社区活跃,有许多程序员在运用,同时Jackson是Spring中默许的JSON/XML解析器
- 便于运用:在Jackso中提供大量的注解,例如咱们常用的时刻格式化注解@JsonFormat
- 洁净的json:创建JSON时洁净、紧凑、体积小等特色
2、注解介绍
2.1 序列化与反序列化注解
2.1.1 @JsonAnyGetter与@JsonAnySetter
@JsonAnyGetter
:将一个map集合中的key/value,序列化成为json。
@JsonAnySetter
:反序列化时,将界说以外的元素经过key/value形式保存到map中。
/**
* @author: jiangjs
* @description: 运用@JsonAnyGetter将map序列化成json
* @date: 2023/6/12 11:17
**/
public class MapToJson {
public MapToJson(){};
public MapToJson(String name){
this.name = name;
};
private String name;
private final Map<String,Object> properties = new HashMap<>();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@JsonAnyGetter
public Map<String,Object> getProperties(){
return properties;
}
@JsonAnySetter
public void setProperties(String key,Object value){
this.properties.put(key,value);
}
}
测验:
private final static Logger log = LoggerFactory.getLogger(UseJacksonApplicationTests.class);
@Test
public void mapToJson() throws JsonProcessingException {
MapToJson getJson = new MapToJson("张三");
getJson.setProperties("key1","特点1");
getJson.setProperties("key2",2);
String jsonStr = new ObjectMapper().writeValueAsString(getJson);
log.info("@JsonAnyGetter序列化Map转json:"+jsonStr);
String json = "{"name":"张三","s":"特点1","p":2}";
MapToJson setJson = new ObjectMapper().readerFor(MapToJson.class).readValue(json);
log.info("@JsonAnySetter反序列化Json转实体:"+setJson.getProperties());
}
输出:
从输出成果能够看出, @JsonAnyGetter
将map中的数据序列化成了json字符串中的一部分内容, @JsonAnySetter
反序列化将json中除了界说的参数外(如:name),其他的都转化成了map。因此咱们在调用第三方接口时,假如对方新增或修改了一些参数时,为了达到适配,能够运用这两个注解。
2.1.2 @JsonGetter与@JsonSetter
@JsonGetter
:序列化时,运用get办法时,重新界说字段的称号。例如:界说的get办法:getNickName(),运用@JsonGetter(“nName”)则json字符串中则为nName
@JsonSetter
:反序列化时,将界说承受数据的字段称号的数据,赋值给实体中的字段。例如:界说set办法:setNickName(String nickName),而@JsonSetter(“nName”)则json字符串中的nName的值则赋值给实体中的nickName。
/**
* @author: jiangjs
* @description: 运用@JsonGetter或@JsonSetter
* @date: 2023/6/12 14:12
**/
public class JsonGetAndSet {
public JsonGetAndSet(String name,String nickName){
this.name = name;
this.nickName = nickName;
}
private String name;
private String nickName;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@JsonGetter("nName")
public String getNickName() {
return nickName;
}
@JsonSetter("nName")
public void setNickName(String nickName) {
this.nickName = nickName;
}
}
测验:
@Test
public void jsonGetAndSet() throws JsonProcessingException {
JsonGetAndSet getJson = new JsonGetAndSet("zhangsan","张三");
String jsonStr = new ObjectMapper().writeValueAsString(getJson);
log.info("@JsonGetter序列化实体转json:"+jsonStr);
String json = "{"name":"zhangsan","nName":"张三"}";
JsonGetAndSet setJson = new ObjectMapper().readerFor(JsonGetAndSet.class).readValue(json);
log.info("@JsonSetter反序列化Json转实体:"+setJson.getName() + "," + setJson.getNickName());
}
输出:
这两个注解能够了解是给字段设置了别号,当咱们不想让客户知道详细字段信息或接收的数据中一个字段要获取另一个字段值时,能够采用这两个注解。
2.1.3 @JsonPropertyOrder
@JsonPropertyOrder
:指定实体字段序列化的次序。
/**
* @author: jiangjs
* @description: 未运用@JsonPropertyOrder
* @date: 2023/6/12 14:35
**/
@Data
@AllArgsConstructor
public class OrderProperty {
private int id;
private String name;
private String nickName;
}
/**
* @author: jiangjs
* @description: 运用@JsonPropertyOrder
* @date: 2023/6/12 14:40
**/
@Data
@AllArgsConstructor
@JsonPropertyOrder({"name","nickName","id"})
public class UseOrderProperty {
private int id;
private String name;
private String nickName;
}
测验:
@Test
public void usePropertyOrder() throws JsonProcessingException {
OrderProperty property = new OrderProperty(1, "zhangsan", "张三");
String json = new ObjectMapper().writeValueAsString(property);
log.info("未运用@JsonPropertyOrder排序:"+json);
UseOrderProperty propertyOrder = new UseOrderProperty(1, "zhangsan", "张三");
String useJson = new ObjectMapper().writeValueAsString(propertyOrder);
log.info("运用@JsonPropertyOrder排序:"+useJson);
}
输出:
2.1.4 @JsonRawValue
@JsonRawValue
:按原样序列化特点值。
/**
* @author: jiangjs
* @description: 运用@JsonRawValue
* @date: 2023/6/12 14:55
**/
@Data
@AllArgsConstructor
public class JsonRawValueDomain {
private String name;
@JsonRawValue
private String json;
}
测验:
@Test
public void useJsonRawValue() throws JsonProcessingException {
JsonRawValueDomain valueDomain = new JsonRawValueDomain("张三", "{"age":30,"gender":"男"}");
String json = new ObjectMapper().writeValueAsString(valueDomain);
log.info("运用@JsonRawValue输出json:"+json);
}
输出:
- 未运用@JsonRawValue进行注解时,则界说json值未序列化,得到的是赋值的String类型数据
- 运用@JsonRawValue进行注解时,则界说json值得到的是序列化后的数据
2.1.5 @JsonValue
@JsonValue
:序列化时只回来注解字段的值。
/**
* @author: jiangjs
* @description:
* @date: 2023/6/12 15:55
**/
@Data
@AllArgsConstructor
public class JsonValueDomain {
private String name;
@JsonValue
private String nickName;
}
测验:
@Test
public void useJsonValue() throws JsonProcessingException {
JsonValueDomain valueDomain = new JsonValueDomain("zhangsan", "张三");
String json = new ObjectMapper().writeValueAsString(valueDomain);
log.info("未运用@JsonValue输出json:"+json);
}
输出:
- 未运用@JsonValue时,回来键值的json
- 运用@JsonValue注解nickName时,则只回来nickName的值。
2.1.6 @JsonRootName
@JsonRootName
:序列化时,给json设置name。
/**
* @author: jiangjs
* @description:
* @date: 2023/6/12 14:35
**/
@Data
@AllArgsConstructor
@JsonRootName(value = "property")
public class OrderProperty {
private int id;
private String name;
private String nickName;
}
测验:
@Test
public void useJsonRootName() throws JsonProcessingException {
OrderProperty property = new OrderProperty(1, "zhangsan", "张三");
String json = new ObjectMapper().writeValueAsString(property);
log.info("未运用@JsonRootName:"+json);
String json = new ObjectMapper().enable(SerializationFeature.WRAP_ROOT_VALUE).writeValueAsString(property);
log.info("运用@JsonRootName:"+json);
}
输出:
- 未运用@JsonRootName,则直接回来json的键值对数据
- 运用@JsonRootName后,在json数据前增加了设置的name。
在运用@JsonRootName时,序列化需求指定enable的值,注解才会收效。
2.1.7 @JsonCreator
@JsonCreator
:反序列化时,调用构造办法或工厂,在反序列化时,能够指定json中的字段与实体字段相匹配。例如:json中字段p,则能够用实体中的c与之相匹配。
/**
* @author: jiangjs
* @description:
* @date: 2023/6/13 9:17
**/
@Data
public class UseJsonCreator {
private String name;
private String nickName;
@JsonCreator
public UseJsonCreator(@JsonProperty("name") String name,
@JsonProperty("nName") String nickName){
this.name = name;
this.nickName = nickName;
}
}
测验:
@Test
public void useJsonRawValue() throws JsonProcessingException {
String json = "{"name":"zhangsan","nName":"张三"}";
UseJsonCreator uc = new ObjectMapper().readerFor(UseJsonCreator.class).readValue(json);
log.info("运用@JsonCreator输出实体:"+uc.getName() + uc.getNickName());
}
输出:
2.1.8 @JacksonInject
@JacksonInject
:反序列化时,被注解的参数,只能经过InjectableValues来增加数据,设置表中主键数据时能够运用。
/**
* @author: jiangjs
* @description:
* @date: 2023/6/13 9:32
**/
@Data
public class UseJacksonInject {
@JacksonInject
private String name;
private String nickName;
}
测验:
@Test
public void useJacksonInject() throws JsonProcessingException {
String json = "{"nickName":"张三"}";
InjectableValues.Std inject = new InjectableValues.Std().addValue(String.class, "zhangsan");
UseJacksonInject uji = new ObjectMapper().reader(inject).forType(UseJacksonInject.class).readValue(json);
log.info("运用@JacksonInject赋值实体:"+uji.getName() + uji.getNickName());
}
输出:
2.1.9 @JsonAlias
@JsonAlias
:给注解字段提供一个或多个别号,反序列化时,依据别号找到对应字段进行赋值。
/**
* @author: jiangjs
* @description:
* @date: 2023/6/13 9:50
**/
@Data
public class UseJsonAlias {
private String name;
@JsonAlias({"nName","pName"})
private String nickName;
}
测验:
@Test
public void useJsonAlias() throws JsonProcessingException {
String json = "{"nName":"张三","name":"zhangsan"}";
UseJsonAlias uji = new ObjectMapper().readerFor(UseJsonAlias.class).readValue(json);
log.info("运用@UseJsonAlias别号赋值实体:"+uji.getName() + uji.getNickName());
}
输出:
2.2 特点注解
2.2.1 @JsonIgnoreProperties、@JsonIgnore、 @JsonIgnoreType
@JsonIgnoreProperties
:序列化时设置疏忽一个或多个字段,只能运用在类上。
@JsonIgnore
:能够了解是 @JsonIgnoreProperties
疏忽一个字段的版本,运用在字段上。
@JsonIgnoreType
:疏忽被注解的类的一切特点,即 @JsonIgnoreProperties
疏忽该类上的一切字段
/**
* @author: jiangjs
* @description:
* @date: 2023/6/13 9:59
**/
@Data
@JsonIgnoreProperties("name")
@AllArgsConstructor
public class UseJsonIgnoreProperties {
private String name;
private String nickName;
@JsonIgnore
private String gender;
private IgnoreClass aClass;
@Data
@JsonIgnoreType
@AllArgsConstructor
public static class IgnoreClass{
private String loginName;
private String passWord;
}
}
测验:
@Test
public void useJsonIgnoreProperties() throws JsonProcessingException {
UseJsonIgnoreProperties.IgnoreClass clazz = new UseJsonIgnoreProperties.IgnoreClass("zs","123456");
UseJsonIgnoreProperties ignoreProperties = new UseJsonIgnoreProperties("zhangsan", "张三","男",clazz);
String json = new ObjectMapper().writeValueAsString(ignoreProperties);
log.info("运用@JsonIgnoreProperties与@JsonIgnore疏忽设置字段:"+json);
}
输出:
2.2.2 @JsonInclude与@JsonIncludeProperties
@JsonInclude
:序列化时,获取符合条件的字段。例如:设置序列化不为null的字段
@JsonIncludeProperties
:用于设置序列化或反序列化时,指定的一个或多个字段。版本2.12及以上才支持。
/**
* @author: jiangjs
* @description:
* @date: 2023/6/13 10:31
**/
@Data
@AllArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIncludeProperties({"nickName","name"})
public class UseJsonInclude {
private String name;
private String nickName;
private String gender;
}
只获取不为null且序列化nickName,name的字段。
测验:
@Test
public void useJsonInclude() throws JsonProcessingException {
UseJsonInclude include = new UseJsonInclude("zhangsan", null, "男");
String json = new ObjectMapper().writeValueAsString(include);
log.info("运用@JsonInclude与@JsonIncludeProperties序列化:"+json);
}
输出:
2.2.3 @JsonAutoDetect
@JsonAutoDetect
:能够设置哪些特点可见或不可见。默许情况下,Jackson 只运用 public 的字段进行序列化和反序列化。没有 public 字段时,会运用 public 的 getters/setters。
能够经过 @JsonAutoDetect 自界说这种行为,指定字段、办法的可见性规矩。
/**
* @author: jiangjs
* @description:
* @date: 2023/6/13 11:12
**/
@AllArgsConstructor
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.PROTECTED_AND_PUBLIC)
public class UseJsonAutoDetect {
private final String name;
private final String nickName;
public String gender;
protected Integer age;
}
设置了PROTECTED_AND_PUBLIC可见
测验:
@Test
public void useJsonAutoDetect() throws JsonProcessingException {
UseJsonAutoDetect autoDetect = new UseJsonAutoDetect("zhangsan", "张三","男",30);
String json = new ObjectMapper().writeValueAsString(autoDetect);
log.info("运用@JsonAutoDetect序列化:"+json);
}
输出:
JsonAutoDetect.Visibility.PROTECTED_AND_PUBLIC
:字段protected和public可见。
JsonAutoDetect.Visibility.ANY
:一切可见
JsonAutoDetect.Visibility.NON_PRIVATE
:除private外可见
JsonAutoDetect.Visibility.PUBLIC_ONLY
:仅public可见
JsonAutoDetect.Visibility.NONE
:禁用JsonAutoDetect
2.3 多态注解
@JsonTypeInfo
:作用于类/接口,说明开启了多态类型处理。
@JsonSubType
:用来罗列子类,当子类类型无法被检测时运用它,与@JsonTypeInfo配合运用
@JsonTypeName
:作用于子类,即给每个子类指定称号。
/**
* @author: jiangjs
* @description: @JsonTypeInfo实现多态
* @date: 2023/6/13 14:12
**/
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME,include = JsonTypeInfo.As.PROPERTY,property="type")
@JsonSubTypes({
@JsonSubTypes.Type(value = Dog.class,name = "dog"),
@JsonSubTypes.Type(value = Cat.class,name = "cat"),
})
@Data
@Accessors(chain = true)
public class Animal {
private String name;
private String color;
}
/**
* @author: jiangjs
* @description:
* @date: 2023/6/13 14:14
**/
@EqualsAndHashCode(callSuper = true)
@JsonTypeName(value = "cat")
@Data
public class Cat extends Animal{
boolean likesCream;
public int lives;
}
/**
* @author: jiangjs
* @description:
* @date: 2023/6/13 14:16
**/
@EqualsAndHashCode(callSuper = true)
@Data
@JsonTypeName(value = "dog")
@Accessors(chain = true)
public class Dog extends Animal{
public double barkVolume;
}
测验:
@Test
public void useJsonTypeInfo() throws JsonProcessingException {
Dog dog = new Dog();
dog.setBarkVolume(10d).setColor("黄白").setName("橙橙");
String json = new ObjectMapper().writeValueAsString(dog);
log.info("运用@JsonTypeInfo多态:"+json);
String cat = "{"name":"橙橙","color":"黄白","barkVolume":10.0,"lives":1,"likesCream":true}";
Animal animal = new ObjectMapper().readerFor(Animal.class).readValue(cat);
log.info("运用@JsonTypeInfo多态:"+animal.getName());
}
当实体被序列化时,会在json中增加了type这个字段,用于区别详细的子类。反序列化时,假如没有增加这个type字段时,则会报错。而type这个字段是在 @JsonTypeInfo
下的property界说
输出:
在@JsonTypeInfo中一些特点
1、use:
JsonTypeInfo.Id.CLASS
:运用完好的类名作为特点标识,例如:上述中dog被序列化后看到其完好的类途径。 “type”:”com.jiashn.useJackson.domain.Dog” ;
JsonTypeInfo.Id.MINIMAL_CLASS
:若基类与子类在同一包类,则运用类名来作为特点标识。例如:dog被序列化后: “type”:”.Dog” ;
JsonTypeInfo.Id.NAME
:与@JsonTypeName一同运用,指定设置的类型称号。例如:Dog子类被设置成dog,序列化后: “type”:”dog” ;
JsonTypeInfo.Id.CUSTOM
:自界说识别码,由 @JsonTypeIdResolver 设置
JsonTypeInfo.Id.NONE
:不适用标识。2、include:可选,指定标识以怎样的方法进行序列化。
JsonTypeInfo.As.PROPERTY
:作为数据的兄弟特点,即与数据在同一级。
JsonTypeInfo.As.EXISTING_PROPERTY
:作为实体中已存在的特点
JsonTypeInfo.As.EXTERNAL_PROPERTY
:作为扩展特点
JsonTypeInfo.As.WRAPPER_OBJECT
:作为一个包装的目标
JsonTypeInfo.As.WRAPPER_ARRAY
:作为一个包装的数组3、property:可选,设置特点符号
2.4 常规注解
2.4.1 @JsonProperty
@ JsonProperty
:指定字段在json显示的特点。
/**
* @author: jiangjs
* @description:
* @date: 2023/6/13 15:06
**/
@Data
@AllArgsConstructor
public class UseJsonProperty {
@JsonProperty("loginName")
private String name;
private String nickName;
}
测验:
@Test
public void useJsonProperty() throws JsonProcessingException {
UseJsonProperty jsonProperty = new UseJsonProperty("zhangsan", "张三");
String json = new ObjectMapper().writeValueAsString(jsonProperty);
log.info("运用@JsonProperty指定特点:" + json);
}
输出:
2.4.2 @JsonFormat
@JsonFormat
:序列化时格式化时刻,这个也是咱们经常用到的一个注解。
/**
* @author: jiangjs
* @description:
* @date: 2023/6/13 15:06
**/
@Data
@AllArgsConstructor
public class UseJsonProperty {
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd kk:mm:ss")
private Date date;
}
测验:
@Test
public void useJsonProperty() throws JsonProcessingException {
UseJsonProperty jsonProperty = new UseJsonProperty("new Date());
String json = new ObjectMapper().writeValueAsString(jsonProperty);
log.info("运用@JsonFormat指定特点:" + json);
}
输出:
pattern
:格式化格式,如:yyyy-MM-dd HH:mm:ss
timezone
:时区,例如:GMT+8
locale
:依据位置序列化后的一种语言格式,例如:zh_CN表明中国
shap
:序列化后的类型,默许:JsonFormat.Shape.ANY
2.4.3 @JsonUnwrapped
@ JsonUnwrapped
:将被注解的实体类数据,与其他字段同一级在json中显示。
/**
* @author: jiangjs
* @description:
* @date: 2023/6/14 10:07
**/
@Data
@AllArgsConstructor
public class UseJsonUnwrapped {
private String name;
@JsonUnwrapped
private Other other;
@Data
@AllArgsConstructor
public static class Other{
private String nickName;
private String gender;
}
}
测验:
@Test
public void useJsonUnwrapped() throws JsonProcessingException {
UseJsonUnwrapped.Other other = new UseJsonUnwrapped.Other("张三", "男");
UseJsonUnwrapped unwrapped = new UseJsonUnwrapped("zhangsan", other);
String json = new ObjectMapper().writeValueAsString(unwrapped);
log.info("运用@JsonFormat指定特点:" + json);
}
输出:
- Other特点未增加@JsonUnwrapped时
- Other特点增加@JsonUnwrapped时
2.4.4 @JsonView
@JsonView
:标识在View中的哪些特点进行序列化或反序列化。
/**
* @author: jiangjs
* @description:
* @date: 2023/6/14 10:18
**/
public class Views {
public static class Public {}
public static class Internal extends Public {}
}
/**
* @author: jiangjs
* @description:
* @date: 2023/6/14 10:15
**/
@Data
@AllArgsConstructor
public class UseJsonView {
@JsonView(Views.Public.class)
private String name;
@JsonView(Views.Public.class)
private String nickName;
@JsonView(Views.Internal.class)
private String gender;
}
测验:
@Test
public void useJsonView() throws JsonProcessingException {
UseJsonView view = new UseJsonView("zhangsan","张三", "男");
String json = new ObjectMapper().writerWithView(Views.Public.class).writeValueAsString(view);
log.info("运用@JsonView序列化json:" + json);
}
输出:
writerWithView()中指定了只显示Views中哪些特点的值。
2.4.5 @JsonManagedReference, @JsonBackReference
@JsonManagedReference, @JsonBackReference
:一同处理父类与子类之间的联系,处理循环。
/**
* @author: jiangjs
* @description:
* @date: 2023/6/14 10:39
**/
@Data
@AllArgsConstructor
public class Parent {
private Integer id;
private String name;
@JsonManagedReference
Child children;
}
/**
* @author: jiangjs
* @description:
* @date: 2023/6/14 10:40
**/
@Data
public class Child {
private String childName;
@JsonBackReference
List<Parent> parent;
public Child(){}
public Child(String childName){this.childName = childName;}
}
测验:
@Test
public void useReference() throws JsonProcessingException {
Child child = new Child("孩子");
Parent parent = new Parent(1, "父辈", child);
String json = new ObjectMapper().writeValueAsString(parent);
log.info("运用@JsonManagedReference, @JsonBackReference序列化json:" + json);
}
输出:
- 未增加注解时
子类中的parent没有赋值,则显示的是null,具有依靠联系
- 增加注解后
子类中没有parent,处理了依靠。
2.4.6 @JsonIdentityInfo
@JsonIdentityInfo
:表明在序列化/反序列化值时应运用目标标识,能够处理循环依靠问题。
/**
* @author: jiangjs
* @description:
* @date: 2023/6/14 10:39
**/
@Data
@Accessors(chain = true)
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,property = "id")
public class IdentityParent {
private Integer id;
private String name;
private List<IdentityChild> children;
}
/**
* @author: jiangjs
* @description:
* @date: 2023/6/14 10:40
**/
@Data
@Accessors(chain = true)
public class IdentityChild {
private int id;
private String childName;
private IdentityParent identityParent;
}
测验:
@Test
public void useJsonIdentityInfo() throws JsonProcessingException {
IdentityChild identityChild = new IdentityChild();
identityChild.setId(2).setChildName("孩子");
IdentityParent parent = new IdentityParent();
parent.setName("父辈").setId(1).setChildren(Collections.singletonList(identityChild));
identityChild.setIdentityParent(parent);
String json = new ObjectMapper().writeValueAsString(parent);
log.info("运用@JsonIdentityInfo序列化json:" + json);
}
输出:
identityChild将IdentityParent初始化的数据赋值给了字段identityParent,但是输出的成果是IdentityParent中的id的值,即指向的是IdentityParent中设置的标识。
2.4.7 @JsonFilter
@JsonFilter:序列化时,指定设置过滤器,设置要输出的字段。
/**
* @author: jiangjs
* @description:
* @date: 2023/6/14 17:23
**/
@Data
@JsonFilter("jsonFilter")
@AllArgsConstructor
public class UseJsonFilter {
private String name;
private String nickname;
}
测验:
@Test
public void useJsonFilter() throws JsonProcessingException {
UseJsonFilter filter = new UseJsonFilter("zhangsan","张三");
SimpleFilterProvider provider = new SimpleFilterProvider()
.addFilter("jsonFilter", SimpleBeanPropertyFilter.filterOutAllExcept("nickname"));
String json = new ObjectMapper().writer(provider).writeValueAsString(filter);
log.info("运用@JsonFilter序列化json:" + json);
}
输出:
jackson的注解就先跟我们提到这,这些注解中有许多咱们能够在日常开发中用到,比如:@JsonAnyGetter和@JsonAnySetter,再确定主要接口字段后,其他不确定字段就能够运用。这些接口要熟练掌握,需求咱们在日常开发中常常用到,期望我的文章对我们有所帮助,工欲善其事,必先利其器,撸起来吧,小伙伴们。
下次咱们来说说jackson的自界说注解以及相关运用。