欢送拜访我的GitHub

https://github.com/zq2599/blog_demos

内容:所有原创文章分类汇总及配套源码,波及Java、Docker、Kubernetes、DevOPS等;

系列文章汇总

  • jackson学习之一:根本信息
  • jackson学习之二:jackson-core
  • jackson学习之三:罕用API操作
  • jackson学习之四:WRAP_ROOT_VALUE(root对象)
  • jackson学习之五:JsonInclude注解
  • jackson学习之六:罕用类注解
  • jackson学习之七:罕用Field注解
  • jackson学习之八:罕用办法注解
  • jackson学习之九:springboot整合(配置文件)
  • jackson学习之十(终篇):springboot整合(配置类)

本篇概览

本文是《jackson学习》系列的第四篇,后面学习了罕用API,能够执行最根本的序列化和反序列化操作,接下来要学习的就是jackson弱小的注解能力,本篇要学的是root对象个性,次要内容如下:

  1. 对于root对象
  2. 测试用的POJO类
  3. 序列化实战
  4. 反序列化实战

对于root对象(WRAP_ROOT_VALUE)

  1. 对于只有<font color="blue">id</font>和<font color="blue">name</font>两个字段的POJO实例来说,失常的序列化后果如下:
{  "id" : 1,  "name" : "book"}
  1. jackson在序列化时,能够在上述json里面再包裹一层,官网叫做<font color="blue">WRAP_ROOT_VALUE</font>,本文中叫做<font color="red">root对象</font>,如下所示,整个json的只有一个键值对,key是<font color="blue">aaabbbccc</font>,value外部才是POJO实例的id和name字段的值:
{  "aaabbbccc" : {    "id" : 2,    "name" : "food"  }}

提前小结

root对象个性提前做个小结,这样如果您工夫无限,仅看这一节即可:

  • 先看序列化场景:
  1. 执行上面代码,jackson在序列化时会减少root对象:
mapper.enable(SerializationFeature.WRAP_ROOT_VALUE);
  1. root对象的key,默认是实例的类名,如果实例有JsonRootName注解,就是该注解的value值;
  2. root对象的value如下所示,相当于<font color="blue">不反对root对象时的序列化后果</font>:
{  "id" : 1,  "name" : "book"}
  • 再看反序列化场景:
  1. 执行上面代码,jackson在反序列化时会先解析root对象:
mapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE);
  1. root对象的key,默认是实例的类名,如果实例有JsonRootName注解,就是该注解的value值;
  2. root对象的value如下所示,相当于<font color="blue">不反对root对象时用来反序列化的json字符串</font>:
{  "id" : 1,  "name" : "book"}

筹备两个POJO类

用比照的形式能够更分明理解JsonRootName的作用,接下来的学习咱们筹备两个POJO类,一个没有JsonRootName注解,另一个有JsonRootName注解:

  1. 名为<font color="blue">Order1.java</font>的,没有JsonRootName注解:
public class Order1 {    private int id;    private String name;    // 省去get、set、toString办法    ...}
  1. 名为<font color="blue">Order2.java</font>的,有JsonRootName注解,value值为<font color="red">aaabbbccc</font>:
import com.fasterxml.jackson.annotation.JsonRootName;@JsonRootName(value = "aaabbbccc")public class Order2 {    private int id;    private String name;    // 省去get、set、toString办法    ...}
  • 可见Order1和Order2的代码是统一的,惟一的不同是Order2带有注解JsonRootName;

序列化

  1. 须要设置WRAP_ROOT_VALUE属性,jackson才会反对root对象,JsonRootName注解才会发挥作用,设置代码如下:
mapper.enable(SerializationFeature.WRAP_ROOT_VALUE);
  1. 写一段代码,在不开启WRAP_ROOT_VALUE属性的时候执行序列化,再开启WRAP_ROOT_VALUE属性执行序列化,比照试试:
public static void main(String[] args) throws Exception {        // 实例化Order1和Order2        Order1 order1 = new Order1();        order1. setId(1);        order1.setName("book");        Order2 order2 = new Order2();        order2. setId(2);        order2.setName("food");        // 没有开启WRAP_ROOT_VALUE的时候        logger.info("没有开启WRAP_ROOT_VALUE\n");        ObjectMapper mapper1 = new ObjectMapper();        // 丑化输入        mapper1.enable(SerializationFeature.INDENT_OUTPUT);        logger.info("没有JsonRootName注解类,序列化后果:\n\n{}\n\n", mapper1.writeValueAsString(order1));        logger.info("有JsonRootName注解的类,序列化后果:\n\n{}\n\n\n\n", mapper1.writeValueAsString(order2));        // 开启了WRAP_ROOT_VALUE的时候        logger.info("开启了WRAP_ROOT_VALUE\n");        ObjectMapper mapper2 = new ObjectMapper();        // 丑化输入        mapper2.enable(SerializationFeature.INDENT_OUTPUT);        // 序列化的时候反对JsonRootName注解        mapper2.enable(SerializationFeature.WRAP_ROOT_VALUE);        logger.info("没有JsonRootName注解类,序列化后果:\n\n{}\n\n", mapper2.writeValueAsString(order1));        logger.info("有JsonRootName注解的类,序列化后果:\n\n{}", mapper2.writeValueAsString(order2));    }
  1. 执行后果如下,JsonRootName在序列化时的作用高深莫测:指定了root对象的key:

反序列化(默认设置)

  1. 在没有做任何设置的时候,上面这个字符串用来反序列化成Order2对象,会胜利吗?
{  "id" : 2,  "name" : "food"}
  1. 试了下是能够的:

  1. 那上面这个字符串能反序列化成Order2对象吗?
{  "aaabbbccc" : {    "id" : 2,    "name" : "food"  }}
  1. 代码和后果如下图所示,反序列化时jackson并不意识<font color="red">aaabbbccc</font>这个key,因为jackson此时并不反对root对象:

  • 小结:默认状况下,反序列化时json字符串不能有root对象;

反序列化(开启UNWRAP_ROOT_VALUE属性)

  1. 如果开启了UNWRAP_ROOT_VALUE属性,用于反序列化的json字符串就必须要有root对象了,开启UNWRAP_ROOT_VALUE属性的代码如下:
mapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE);
  1. 代码和后果如下图,可见带有root对象的json字符串,能够反序列化胜利,root对象的key就是JsonRootName注解的value属性:

  1. 值得注意的是,上述json字符串中,root对象的key为<font color="blue">aaabbbccc</font>,这和Order2的<font color="blue">JsonRootName</font>注解的value值是统一的,<font color="red">如果不统一就会反序列化失败</font>,如下图:

  • 至此,jackson的WRAP_ROOT_VALUE个性就学习实现了,在web开发时这是个很罕用的性能,用于在最里面包裹一层,以便整体上增加额定的内容,心愿能给您带来参考;

你不孤独,欣宸原创一路相伴

  1. Java系列
  2. Spring系列
  3. Docker系列
  4. kubernetes系列
  5. 数据库+中间件系列
  6. DevOps系列

欢送关注公众号:程序员欣宸

微信搜寻「程序员欣宸」,我是欣宸,期待与您一起畅游Java世界...
https://github.com/zq2599/blog_demos