写点什么

java 浅拷贝 BeanUtils.copyProperties 引发的 RPC 异常

  • 2024-09-24
    北京
  • 本文字数:820 字

    阅读完需:约 3 分钟

背景

近期参与了一个攻坚项目,前期因为其他流程原因,测试时间已经耽搁了好几天了,本以为已经解决了卡点,后续流程应该顺顺利利的,没想到 人在地铁上,bug 从咚咚来~


没有任何修改的服务接口,抛出异常:


java.lang.ClassCastException: java.util.HashMap cannot be cast to cn.xxx.xxx.xxx.xxx.BatchInfo

排查过程

1、作为资深写 bug 的老司机,第一感觉是传参的报文格式有问题了,可以通过模拟报文排查。于是乎,在群里圈了服务提供方同学 B 看下,BG 快速的用测试工具+本地 debug 的方式,验证了下报文格式,发现居然都调用成功了。。。


2、同步服务调用同学 L,重点关注:1)、调用方的序列化方式;2)、最近代码改动逻辑是否有问题。L 同学确认自己逻辑没有问题后,同步 B 同学和 S 同学,看内部是否有什么处理逻辑。。。


3、第二天早上一来,快速写了单测,确认服务端收到的报文格式,的确没有问题。于是乎,开始扒代码。。。发现可疑的代码:


BeanUtils.copyProperties(item,cargoInfo)


private List<CargoInfo> convertToCargoInfo(OutboundEventCallbackRequest outboundEventCallbackRequest) {        return outboundEventCallbackRequest.getCargos().stream().map(item -> {            CargoInfo cargoInfo = new CargoInfo();            BeanUtils.copyProperties(item, cargoInfo);            return cargoInfo;    }).collect(Collectors.toList());}
复制代码


PS:客户端 &服务端类关系



因为 BeanUtils.copyProperties 属于浅拷贝,而浅拷贝只是调用子对象的 set 方法,并没有将所有属性拷贝(引用的一个内存地址)。所以将在进行调用时,JSF 会因为反序列化时找不到对应的类,就会将其转换为 Map。


直观图如下:



以上,初步定位原因,解决方式也就清晰了。

解决方案

去掉 BeanUtils.copyProperties,进行手动赋值。最终解决了这个问题。

后续反思

1、想起王东岳老师的那句话,越原始的越稳定~


2、如果这种转换比较多,建议使用 MapStruct


3、谨慎使用 BeanUtils.copyProperties,请看:



发布于: 刚刚阅读数: 6
用户头像

拥抱技术,与开发者携手创造未来! 2018-11-20 加入

我们将持续为人工智能、大数据、云计算、物联网等相关领域的开发者,提供技术干货、行业技术内容、技术落地实践等文章内容。京东云开发者社区官方网站【https://developer.jdcloud.com/】,欢迎大家来玩

评论

发布
暂无评论
java浅拷贝BeanUtils.copyProperties引发的RPC异常_京东科技开发者_InfoQ写作社区