背景
近期參與了一個(gè)攻堅(jiān)項(xiàng)目,前期因?yàn)槠渌鞒淘?,測(cè)試時(shí)間已經(jīng)耽擱了好幾天了,本以為已經(jīng)解決了卡點(diǎn),后續(xù)流程應(yīng)該順順利利的,沒想到 人在地鐵上,bug從咚咚來~
沒有任何修改的服務(wù)接口,拋出異常:
java.lang.ClassCastException: java.util.HashMap cannot be cast to cn.xxx.xxx.xxx.xxx.BatchInfo
排查過程
1、作為資深寫bug的老司機(jī),第一感覺是傳參的報(bào)文格式有問題了,可以通過模擬報(bào)文排查。于是乎,在群里圈了服務(wù)提供方同學(xué)B看下,BG快速的用測(cè)試工具+本地debug的方式,驗(yàn)證了下報(bào)文格式,發(fā)現(xiàn)居然都調(diào)用成功了。。。
2、同步服務(wù)調(diào)用同學(xué)L,重點(diǎn)關(guān)注:1)、調(diào)用方的序列化方式;2)、最近代碼改動(dòng)邏輯是否有問題。L同學(xué)確認(rèn)自己邏輯沒有問題后,同步B同學(xué)和S同學(xué),看內(nèi)部是否有什么處理邏輯。。。
3、第二天早上一來,快速寫了單測(cè),確認(rèn)服務(wù)端收到的報(bào)文格式,的確沒有問題。于是乎,開始扒代碼。。。發(fā)現(xiàn)可疑的代碼:
BeanUtils.copyProperties(item,cargoInfo)
private List convertToCargoInfo(OutboundEventCallbackRequest outboundEventCallbackRequest) { return outboundEventCallbackRequest.getCargos().stream().map(item -> { CargoInfo cargoInfo = new CargoInfo(); BeanUtils.copyProperties(item, cargoInfo); return cargoInfo; }).collect(Collectors.toList()); }
PS:客戶端&服務(wù)端類關(guān)系
因?yàn)锽eanUtils.copyProperties屬于淺拷貝,而淺拷貝只是調(diào)用子對(duì)象的set方法,并沒有將所有屬性拷貝(引用的一個(gè)內(nèi)存地址)。所以將在進(jìn)行調(diào)用時(shí),JSF會(huì)因?yàn)榉葱蛄谢瘯r(shí)找不到對(duì)應(yīng)的類,就會(huì)將其轉(zhuǎn)換為Map。
直觀圖如下:
?
以上,初步定位原因,解決方式也就清晰了。
解決方案
去掉BeanUtils.copyProperties,進(jìn)行手動(dòng)賦值。最終解決了這個(gè)問題。
?
后續(xù)反思
1、想起王東岳老師的那句話,越原始的越穩(wěn)定~
2、如果這種轉(zhuǎn)換比較多,建議使用MapStruct
3、謹(jǐn)慎使用BeanUtils.copyProperties,請(qǐng)看:
?
?
審核編輯 黃宇
-
JAVA
+關(guān)注
關(guān)注
19文章
2946瀏覽量
104362 -
RPC
+關(guān)注
關(guān)注
0文章
110瀏覽量
11483
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論