学无先后,达者为师

网站首页 前端文档 正文

(ObjectMapper)Json转化对象的基本原理

作者:搏·梦 更新时间: 2022-05-25 前端文档

文章目录

  • 1. 前言
  • 2. 先说结论
  • 3. 证明结论
  • 4. 使用@JsonAutoDetect定义字段、方法的访问可见性规则

1. 前言

  1. 在实际开发过程中,会经常接收Json字符串并转化为相应对象,而这个转化过程中若报错,无非提示,没有set方法,或者没有get方法,或者静态内部类没有默认构造函数静态内部类没有带全部参数构造函数无法转化多了某某field属性等等
  2. 因此,在大多数开发的过程中,我们自然会在实体类对象上,一股脑加上 @Data,@NoArgsConstructor,@AllArgsConstructor,@JsonIgnoreProperties(ignoreUnknown = true),甚至让实体类变量与json内部key字段起名完全一样,这确实可以解决百分之九十的问题。
  3. 剩下百分之十的问题如下(例子):
    在这里插入图片描述
    见鬼了,属性名字完全一致,该有的东西都有了,为什么还是转化失败呢?这待我慢慢细说一下。

2. 先说结论

  1. 在ObjectMapper json转化对象过程中,可以单独使用set方法,或field属性(强调是public 属性),或get方法,进行变量属性赋值。
  2. 若都存在,优先级是:set方法 > field属性(强调是public 属性) > get方法
  3. 容易遗忘点:在使用set方法,get方法的时候,请让实体类的属性名 第二个字符不要大写,不要大写,不要大写,因为在使用上述方法的时候,例如属性名xAge,对应的标准set方法,则是setXAge(),而在使用set方法转化的时候,会先找到setXAge()方法,并把set去掉,将后面遇到大写字符变成小写,直到遇到小写字符才会停止,此时得到的是 xage,显然与 属性名xAge 不一样,因此无法正确转化赋值。

3. 证明结论

先准备如下例子:
在这里插入图片描述
开始跟踪源码(请忽略一些细节)
代码会收集可以被转化的属性,如下:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在_addGetterMethod()或者_addSetterMethod()方法中,都会去获取方法名,并截掉对应的get/set方法前缀,获取到对应的属性名
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

收集器 收集好可以被转化的属性之后,就要生成对应的赋值的工具对象
这样子解释吧,比如转化这里肯定是使用反射的方式,对于set方法,使用 invoke方法,而field属性,使用filed.set()方法。
在这里插入图片描述
这里则是对收集到的属性生成对应的赋值方法(姑且可以这样子认为), 从代码上看,可以看出有顺序之分,set方法,field,get,构造。
之后开始赋值了:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

最后结果:
在这里插入图片描述

4. 使用@JsonAutoDetect定义字段、方法的访问可见性规则

  1. 上面证明结论的时候,属性字段设置public可以赋值成功,但实体类并不想直接让属性字段暴露出来,可是又想赋值,此时我们可以使用@JsonAutoDetect,改变属性的可见性,这里的修改可见性仅仅是让json转化的时候,认为是可见而已,相当于一个标记,实际上外部调用该类属性,还是没办法类.字段属性

    public enum Visibility {
            ANY, 					// 所有的访问修饰符
            NON_PRIVATE, 			// 除 private 之外的
            PROTECTED_AND_PUBLIC, 	// 允许 protected、public
            PUBLIC_ONLY, 			// 只允许 public
            NONE, 					// 禁用 AutoDetect
            DEFAULT;
        }
    

    证明:
    在这里插入图片描述

  2. 实际上,上面的set方法/get方法赋值也是建立在public,若set方法,或者get方法不是public也无法赋值,证明:
    在这里插入图片描述
    通过@JsonAutoDetect 修改方法可见性
    在这里插入图片描述

  3. 源码上 在addField()以及addMethod()方法的时候,也有判断 可见性,以field为例子:
    在这里插入图片描述

原文链接:https://blog.csdn.net/xueyijin/article/details/124083389

栏目分类
最近更新