jackson学习之四:WRAP_ROOT_VALUE(root对象)

简介: 了解jackson的WRAP_ROOT_VALUE(root对象)特性

欢迎访问我的GitHub

这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos

系列文章汇总

{
   
   
  "id" : 1,
  "name" : "book"
}
  • jackson在序列化时,可以在上述json外面再包裹一层,官方叫做WRAP_ROOT_VALUE,本文中叫做root对象,如下所示,整个json的只有一个键值对,key是aaabbbccc,value内部才是POJO实例的id和name字段的值:
{
   
   
  "aaabbbccc" : {
   
   
    "id" : 2,
    "name" : "food"
  }
}

提前小结

root对象特性提前做个小结,这样如果您时间有限,仅看这一节即可:

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

准备两个POJO类

用对比的方式可以更清楚了解JsonRootName的作用,接下来的学习咱们准备两个POJO类,一个没有JsonRootName注解,另一个有JsonRootName注解:

  • 名为Order1.java的,没有JsonRootName注解:
public class Order1 {
   
   
    private int id;
    private String name;
  // 省去get、set、toString方法
  ...
}
  • 名为Order2.java的,有JsonRootName注解,value值为aaabbbccc
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;

    序列化

  • 需要设置WRAP_ROOT_VALUE属性,jackson才会支持root对象,JsonRootName注解才会发挥作用,设置代码如下:
mapper.enable(SerializationFeature.WRAP_ROOT_VALUE);
  • 写一段代码,在不开启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));
    }
  • 执行结果如下,JsonRootName在序列化时的作用一目了然:指定了root对象的key:
    在这里插入图片描述

    反序列化(默认设置)

  • 在没有做任何设置的时候,下面这个字符串用来反序列化成Order2对象,会成功吗?
{
   
   
  "id" : 2,
  "name" : "food"
}
  • 试了下是可以的:
    在这里插入图片描述
  • 那下面这个字符串能反序列化成Order2对象吗?
{
   
   
  "aaabbbccc" : {
   
   
    "id" : 2,
    "name" : "food"
  }
}
  • 代码和结果如下图所示,反序列化时jackson并不认识aaabbbccc这个key,因为jackson此时并不支持root对象:
    在这里插入图片描述
  • 小结:默认情况下,反序列化时json字符串不能有root对象;

    反序列化(开启UNWRAP_ROOT_VALUE属性)

  • 如果开启了UNWRAP_ROOT_VALUE属性,用于反序列化的json字符串就必须要有root对象了,开启UNWRAP_ROOT_VALUE属性的代码如下:
mapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE);
  • 代码和结果如下图,可见带有root对象的json字符串,可以反序列化成功,root对象的key就是JsonRootName注解的value属性:
    在这里插入图片描述
  • 值得注意的是,上述json字符串中,root对象的key为aaabbbccc,这和Order2的JsonRootName注解的value值是一致的,如果不一致就会反序列化失败,如下图:
    在这里插入图片描述
  • 至此,jackson的WRAP_ROOT_VALUE特性就学习完成了,在web开发时这是个很常用的功能,用于在最外面包裹一层,以便整体上添加额外的内容,希望能给您带来参考;

欢迎关注博客园:程序员欣宸

学习路上,你不孤单,欣宸原创一路相伴...

相关文章
|
iOS开发
ElasticSearch-Head浏览器插件离线安装
ElasticSearch-Head浏览器插件离线安装
875 0
|
SQL 关系型数据库 MySQL
将MySQL 数据迁移到 PostgreSQL
将MySQL 数据迁移到 PostgreSQL 可以采用以下步骤: 安装 PostgreSQL 数据库:首先,需要安装 PostgreSQL 数据库。可以从官方网站(https://www.postgresql.org/)下载最新版本的 PostgreSQL,并根据官方指南进行安装。 创建 PostgreSQL 数据库:在 PostgreSQL 中创建与 MySQL 数据库相对应的数据库。可以使用 pgAdmin 或命令行工具(如 psql)来创建数据库。例如,如果在 MySQL 中有一个名为 "mydb" 的数据库,那么可以在 PostgreSQL 中创建一个具有相同名称的数据库。 导
4551 0
|
7月前
|
计算机视觉
YOLOv11改进策略【卷积层】| ICCV-2023 引入Dynamic Snake Convolution动态蛇形卷积,改进C3k2
YOLOv11改进策略【卷积层】| ICCV-2023 引入Dynamic Snake Convolution动态蛇形卷积,改进C3k2
308 0
YOLOv11改进策略【卷积层】| ICCV-2023 引入Dynamic Snake Convolution动态蛇形卷积,改进C3k2
企业微信开发之获取media_id的值
企业微信开发之获取media_id的值
458 0
|
4月前
|
弹性计算 Docker 容器
构建dify
本教程介绍如何在ECS服务器上使用Docker构建Dify。首先拉取最新镜像`langgenius/dify-web:latest`,然后通过命令运行该镜像,映射端口并设置环境变量。需在安全组中添加入方向规则,放行指定端口(如3000)。完成后保存规则,初始化安装Dify,并登录Web界面验证部署是否成功。
|
6月前
|
存储 人工智能 固态存储
轻量级AI革命:无需GPU就能运算的DeepSeek-R1-1.5B模型及其低配部署指南
随着AI技术发展,大语言模型成为产业智能化的关键工具。DeepSeek系列模型以其创新架构和高效性能备受关注,其中R1-1.5B作为参数量最小的版本,适合资源受限场景。其部署仅需4核CPU、8GB RAM及15GB SSD,适用于移动对话、智能助手等任务。相比参数更大的R1-35B与R1-67B+,R1-1.5B成本低、效率高,支持数学计算、代码生成等多领域应用,是个人开发者和初创企业的理想选择。未来,DeepSeek有望推出更多小型化模型,拓展低资源设备的AI生态。
1226 8
|
6月前
|
人工智能 自动驾驶 安全
什么是AGI
通用人工智能(AGI)指具备或超越人类智能的机器系统,能跨领域学习、推理和解决问题。其核心特点包括跨领域能力、自主学习与推理、类人思维模式及自适应性。目前AGI仍处早期阶段,但大模型和多模态技术正推动其从理论走向应用,如自动驾驶、科学研究和工业自动化等。尽管前景广阔,AGI仍面临技术瓶颈、伦理安全和资源需求等挑战。未来,AGI有望重塑产业和社会生活方式。
4448 2
|
11月前
|
Java API
异步任务编排神器CompletableFuture
【10月更文挑战第10天】CompletableFuture是JDK8并发包中引入的强大工具,用于处理复杂的异步任务编排。它提供了丰富的API,支持任务的串行、并行、组合及异常处理,适用于需要高效管理和协调多个异步操作的场景。例如,网页加载时需从多个服务异步获取数据,CompletableFuture可以有效提升性能和响应速度。使用时应注意异常处理和合理选择线程池,以确保程序稳定性和效率。
异步任务编排神器CompletableFuture
|
缓存 安全 Java
Spring框架中Bean是如何加载的?从底层源码入手,详细解读Bean的创建流程
从底层源码入手,通过代码示例,追踪AnnotationConfigApplicationContext加载配置类、启动Spring容器的整个流程,并对IOC、BeanDefinition、PostProcesser等相关概念进行解释
1431 25
Spring框架中Bean是如何加载的?从底层源码入手,详细解读Bean的创建流程