【LSP】Java变量命名前俩个字母仅含有一个大写字母的坑

编程开发   © 文章版权由 admin 解释,禁止匿名转载

#楼主# 2020-10-11

背景
前几周在做项目fetch切换,即将HttpUtils调用改成使用Feign调用。大概代码如下:

// 原代码
String resultJson = HttpUtil.get(url + "/fin/test?code=" + code, null);
RespDTO respDTO = JSON.parseObject(resultJson, new TypeReference>() {});

// 现代码如下
RespDTO respDTO = urlClient.getTest(code);
代码上线后,出现了异常。表现为:respDTO的某个字段为null,但是第三方是有传过来这个值的。

问题复现

问题分析
既然请求返回数据,但接收对象没有对应的值,那就说明字符串没有反序列化到指定的变量名上。改之前是使用FastJson反序列化数据,改之后的Feign默认是采用Jackson反序列化数据。那么为什么FastJson可以反序列化aFiled而Jackson不可以呢?

FastJson是根据变量名称来反序列化的,也就是说它接收到aFiled数据,就会到对象找aFiled变量名,然后附上值;而Jackson默认是根据JavaBean规范找到对应属性后再赋值,也就是说Jackson并没有在这个对象找到aFiled属性。

JavaBean属性名称跟变量名称是不一定相同的。JavaBean是通过对象的get、set方法来确定对象属性,其属性名称是由其对象变量来决定的,通常的逻辑是:将属性首字母转成大写。但也有例外就是,前俩个字母都是大写的情况:

而Jackson根据get、set方法来确定属性的名称。而变量前俩个字母含有一个大写字母对应的属性名称会很怪。如下:

我们项目上使用的是lombok,其生成的get、set方法是不遵循JavaBean规范的,只是将变量名的首字母大写而已,所以它生成aFiled的方法是getAFiled。
所以,Jackson在接收到aFiled属性值,它会到对象找setaFiled方法,自然这个对象是没有这个方法的,所以就没映射到aFiled字段上。

解决办法
jackson可以使用@JsonProperty注解来指定属性名称。

总结
出现这个就是因为JavaBean规范对前俩个字母含有大写字母的变量名做了特殊处理。 Jackson遵循JavaBean规范来反序列化,而项目使用的Lombok插件是不遵循JavaBean规范。

成为第一个回答人

评论

登录后才可发表内容
  • 主题

    88

  • 帖子

    1748

  • 关注者

    0

Copyright © 2019 凯特网.   Powered by HYBBS 2.3.4  

Runtime:0.0816s Mem:2123Kb