0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

java淺拷貝BeanUtils.copyProperties引發(fā)的RPC異常

京東云 ? 來源:jf_75140285 ? 作者:jf_75140285 ? 2024-08-13 17:11 ? 次閱讀

背景

近期參與了一個(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)系

wKgZoma7I12Adv4CAAaUrZ8XgAk384.png

因?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。

直觀圖如下:

wKgaoma7I12ANFYMAAJJs4c9l80256.png

?

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

解決方案

去掉BeanUtils.copyProperties,進(jìn)行手動(dòng)賦值。最終解決了這個(gè)問題。

?

后續(xù)反思

1、想起王東岳老師的那句話,越原始的越穩(wěn)定~

2、如果這種轉(zhuǎn)換比較多,建議使用MapStruct

3、謹(jǐn)慎使用BeanUtils.copyProperties,請(qǐng)看:

wKgZoma7I16AVHfIAAZyJNafGQM035.png

?

?


審核編輯 黃宇

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • JAVA
    +關(guān)注

    關(guān)注

    19

    文章

    2946

    瀏覽量

    104362
  • RPC
    RPC
    +關(guān)注

    關(guān)注

    0

    文章

    110

    瀏覽量

    11483
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    Java中的常用異常處理方法 java推薦

    Java中,異常情況分為Exception(異常)和Error(錯(cuò)誤)兩大類,Java異常通常是指程序運(yùn)行過程中出現(xiàn)的非正常情況,如用戶輸
    發(fā)表于 01-19 17:26

    為什么移植ucosii進(jìn)入hardfault會(huì)引發(fā)異常?

    移植完ucosii后,運(yùn)行了一下,發(fā)現(xiàn)在任務(wù)調(diào)度時(shí)進(jìn)入hardfault異常經(jīng)過調(diào)試后發(fā)現(xiàn)是在OS_Sched()函數(shù)運(yùn)行結(jié)束時(shí)引發(fā)異常,這個(gè)是調(diào)試截圖,好像是在出棧指令pop引發(fā)
    發(fā)表于 08-29 04:35

    請(qǐng)問哪位大神可以詳細(xì)介紹JavaScript拷貝和深拷貝?

    JavaScript數(shù)據(jù)類型JavaScript拷貝和深拷貝
    發(fā)表于 11-05 07:16

    Java異常處理及其應(yīng)用

    Java異常處理引出 假設(shè)您要編寫一個(gè) Java 程序,該程序讀入用戶輸入的一行文本,并在終端顯示該文本。 程序如下: 1 import java.io.*;2 public c
    發(fā)表于 11-09 12:03 ?15次下載

    java異常處理的設(shè)計(jì)與重構(gòu)

    尋找出錯(cuò)的根源?但是如果一個(gè)項(xiàng)目異常處理設(shè)計(jì)地過多,又會(huì)嚴(yán)重影響到代碼質(zhì)量以及程序的性能。因此,如何高效簡潔地設(shè)計(jì)異常處理是一門藝術(shù),本文下面先講述Java異常機(jī)制最基礎(chǔ)的知識(shí),然后給
    發(fā)表于 09-27 15:40 ?1次下載
    <b class='flag-5'>java</b><b class='flag-5'>異常</b>處理的設(shè)計(jì)與重構(gòu)

    Java常見內(nèi)存溢出異常分析

    Java 堆是用來存儲(chǔ)對(duì)象實(shí)例的, 因此如果我們不斷地創(chuàng)建對(duì)象, 并且保證 GC Root 和創(chuàng)建的對(duì)象之間有可達(dá)路徑以免對(duì)象被垃圾回收, 那么當(dāng)創(chuàng)建的對(duì)象過多時(shí), 會(huì)導(dǎo)致 heap 內(nèi)存不足, 進(jìn)而引發(fā) OutOfMemoryError
    發(fā)表于 11-28 12:48 ?1228次閱讀

    C#拷貝與深拷貝區(qū)別解析

     所謂拷貝就是將對(duì)象中的所有字段復(fù)制到新的副本對(duì)象中;拷貝對(duì)于值類型與引用類型的方式有區(qū)別,值類型字段的值被復(fù)制到副本中后,在副本中的修改不會(huì)影響源對(duì)象對(duì)應(yīng)的值;然而對(duì)于引用類型的
    發(fā)表于 11-29 08:32 ?2.6w次閱讀
    C#<b class='flag-5'>淺</b><b class='flag-5'>拷貝</b>與深<b class='flag-5'>拷貝</b>區(qū)別解析

    java教程之如何進(jìn)行Java異常處理?

    本文檔的主要內(nèi)容詳細(xì)介紹的是java教程之如何進(jìn)行Java異常處理?
    發(fā)表于 09-28 17:16 ?0次下載

    Python如何防止數(shù)據(jù)被修改Python中的深拷貝拷貝的問題說明

    在平時(shí)工作中,經(jīng)常涉及到數(shù)據(jù)的傳遞。在數(shù)據(jù)傳遞使用過程中,可能會(huì)發(fā)生數(shù)據(jù)被修改的問題。為了防止數(shù)據(jù)被修改,就需要再傳遞一個(gè)副本,即使副本被修改,也不會(huì)影響原數(shù)據(jù)的使用。為了生成這個(gè)副本,就產(chǎn)生了拷貝——今天就說一下Python中的深拷貝
    的頭像 發(fā)表于 03-30 09:54 ?2994次閱讀
    Python如何防止數(shù)據(jù)被修改Python中的深<b class='flag-5'>拷貝</b>與<b class='flag-5'>淺</b><b class='flag-5'>拷貝</b>的問題說明

    Java異常的習(xí)題和代碼分析

    Java異常的習(xí)題和代碼分析
    發(fā)表于 07-08 14:54 ?5次下載
    <b class='flag-5'>Java</b><b class='flag-5'>異常</b>的習(xí)題和代碼分析

    C++之拷貝構(gòu)造函數(shù)的copy及深copy

    C++編譯器會(huì)默認(rèn)提供構(gòu)造函數(shù);無參構(gòu)造函數(shù)用于定義對(duì)象的默認(rèn)初始化狀態(tài);拷貝構(gòu)造函數(shù)在創(chuàng)建對(duì)象時(shí)拷貝對(duì)象的狀態(tài);對(duì)象的拷貝拷貝和深
    的頭像 發(fā)表于 12-24 15:31 ?671次閱讀

    C++面向?qū)ο缶幊讨械纳?b class='flag-5'>拷貝和拷貝

    可能對(duì)于Java程序員來說,很少遇到深淺拷貝問題,但是對(duì)于C++程序員來說可謂是又愛又恨。。
    的頭像 發(fā)表于 03-30 12:53 ?714次閱讀
    C++面向?qū)ο缶幊讨械纳?b class='flag-5'>拷貝</b>和<b class='flag-5'>淺</b><b class='flag-5'>拷貝</b>

    C++深拷貝拷貝詳解

    當(dāng)類的函數(shù)成員存在指針成員時(shí)會(huì)產(chǎn)生深拷貝拷貝和問題。
    發(fā)表于 08-21 15:05 ?308次閱讀
    C++深<b class='flag-5'>拷貝</b>和<b class='flag-5'>淺</b><b class='flag-5'>拷貝</b>詳解

    Python中拷貝與深拷貝的操作

    【例子】拷貝與深拷貝中 list1 = [ 123 , 456 , 789 , 213 ]list2 = list1list3 = list1[:] print (list2) # [ 123
    的頭像 發(fā)表于 11-02 10:58 ?350次閱讀

    Java怎么排查oom異常

    Java中的OOM(Out of Memory)異常是指當(dāng)Java虛擬機(jī)的堆內(nèi)存不足以容納新的對(duì)象時(shí)拋出的異常。OOM異常是一種常見的運(yùn)行時(shí)
    的頭像 發(fā)表于 12-05 13:47 ?1120次閱讀