中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁(yè) > news >正文

京東網(wǎng)上商城投訴電話天津seo托管

京東網(wǎng)上商城投訴電話,天津seo托管,軟件工程師多少錢一個(gè)月,四川省住房和城鄉(xiāng)建設(shè)廳網(wǎng)站域名使用基于jvm-sandbox的對(duì)三層嵌套類型的改造 問(wèn)題背景 先簡(jiǎn)單介紹下基于jvm-sandbox的imock工具,是Java方法級(jí)別的mock,操作就是監(jiān)聽指定方法,返回指定的mock內(nèi)容。 jvm-sandbox 利用字節(jié)碼操作和自定義類加載器的技術(shù),將原始方法…

使用基于jvm-sandbox的對(duì)三層嵌套類型的改造

問(wèn)題背景

先簡(jiǎn)單介紹下基于jvm-sandbox的imock工具,是Java方法級(jí)別的mock,操作就是監(jiān)聽指定方法,返回指定的mock內(nèi)容。

jvm-sandbox 利用字節(jié)碼操作和自定義類加載器的技術(shù),將原始方法替換為模擬代碼,從而在應(yīng)用程序中實(shí)現(xiàn)方法級(jí)別的模擬。這種方法非常強(qiáng)大,但也需要對(duì)字節(jié)碼操作、類加載機(jī)制和 JVM 內(nèi)部原理有一定的理解。

公司要搭建一個(gè)方法級(jí)別的后端mock平臺(tái),因此我在imock的基礎(chǔ)上進(jìn)行二次開發(fā)進(jìn)行使用。

問(wèn)題描述

在mock某個(gè)三方接口的方法時(shí)遇到報(bào)錯(cuò):ava.lang.ClassCastException: com.alibaba.fastjson.JSONObject cannot be cast to com.travelsky.angeldoe.output.PassengerFlightInfo

看樣子是本來(lái)應(yīng)該是JSONObject 無(wú)法轉(zhuǎn)化成PassengerFlightInfo類型,通過(guò)日志排查問(wèn)題,定位到報(bào)錯(cuò)代碼。

PassengerFlightInfo?passengerFlightInfo?=?JSON.parseObject(out
?.getPassengerFlightInfoList().get(0).toString(),?PassengerFlightInfo.class);

線上服務(wù)沒(méi)有報(bào)錯(cuò),測(cè)試mock環(huán)境報(bào)錯(cuò),那么顯然是數(shù)據(jù)的問(wèn)題,通過(guò)Arthas追蹤方法返回的bean對(duì)比發(fā)現(xiàn),差異就是線上的PassengerFlightInfo是一個(gè)bean,測(cè)試的PassengerFlightInfo是一個(gè)object。差異由此出現(xiàn)。

image-20230810214520907
image-20230810214520907
image-20230810231158842
image-20230810231158842

那么問(wèn)題的關(guān)鍵就在于,如何通過(guò)mock工具把object提前轉(zhuǎn)成bean。

解決方案

改造mock agent工具思路:通過(guò)我們的mock-module.jar實(shí)現(xiàn)。

  1. 根據(jù)PsrInfoOutputBean初步解析returnObject,獲取list中的object
  2. 將object解析成PassengerFlightInfo,再通過(guò)反射技術(shù)將bean反射回PsrInfoOutputBean

代碼實(shí)現(xiàn)

//針對(duì)cki特殊類型PsrInfoOutputBean
case?3:
????//獲取advice返回類型的類加載器
????ClassLoader?behaviorClassLoader?=?advice.getBehavior().getReturnType().getClassLoader();
????//加載最外層PsrInfoOutputBean
????Class<?>?targetClass?=?behaviorClassLoader.loadClass(ro.getClassNames()[0]);
????LogUtil.info2("targetClass=",?targetClass.toString());
????//根據(jù)目標(biāo)類解析returnData
????Object?res1?=?JSON.parseObject(ro.getReturnData(),?targetClass);
????//賦值保存做對(duì)比
????Object?res0?=?res1;
????LogUtil.info2("res1-before=",?res1.toString());
????//?通過(guò)反射獲取passengerFlightInfoList
????List<Object>?passengerFlightInfoList?=?(List<Object>)?targetClass.getMethod("getPassengerFlightInfoList").invoke(res1);
????LogUtil.info2("passengerFlightInfoList=",?passengerFlightInfoList.toString());
????if?(!passengerFlightInfoList.isEmpty())?{
????????//?獲取?passengerFlightInfoList?列表中的第一個(gè)元素
????????Object?firstPassengerFlightInfoList?=?passengerFlightInfoList.get(0);
????????LogUtil.info2("firstPassengerFlightInfoList=",?firstPassengerFlightInfoList.toString());
????????//?將?firstFlightInfo?轉(zhuǎn)換成?JSON?字符串
????????String?firstFlightInfoJson?=?JSON.toJSONString(firstPassengerFlightInfoList);
????????//?獲取第三層額外目標(biāo)?Bean?類的類名,使用同一類加載器
????????Class<?>?targetBeanClass?=?behaviorClassLoader.loadClass(ro.getClassNames()[2]);
????????LogUtil.info2("targetBeanClass=",?targetBeanClass.toString());
????????//根據(jù)類解析成bean
????????Object?targetBean?=?JSON.parseObject(firstFlightInfoJson,?targetBeanClass);
????????LogUtil.info2("targetBean=",?targetBean.toString());
????????//?創(chuàng)建一個(gè)新的passengerFlightInfoListNew?將?targetBean?添加到?passengerFlightInfoList?中
????????List<Object>?passengerFlightInfoListNew?=?new?ArrayList<>();
????????passengerFlightInfoListNew.add(targetBean);
????????//?設(shè)置?passengerFlightInfoList?屬性回?res1
????????try?{
????????????//?執(zhí)行反射方法,把passengerFlightInfoListNew反射回res
????????????Method?method?=?targetClass.getMethod("setPassengerFlightInfoList",?List.class);
????????????method.invoke(res1,?passengerFlightInfoListNew);
????????}?catch?(Exception?e)?{
????????????//?捕獲異常并打印日志
????????????LogUtil.info2("Error?occurred?while?invoking?method:=",?e.getMessage()+"|"+e);
????????}
????}
????LogUtil.info2("前后的兩個(gè)類equals嗎?=",?String.valueOf(res1.equals(res0)));
????LogUtil.info2("res1-after=",?res1.toString());
????ProcessController.returnImmediately(res1);
????break;

遇到的坑

外部獲取的類名不能直接通過(guò)Class.forName加載,如下代碼所示:

?//?使用目標(biāo)?Bean?類名解析?JSON?字符串成目標(biāo)?Bean
????????Class<?>?targetBeanClass?=?Class.forName(targetBeanClassName);

實(shí)際會(huì)報(bào)錯(cuò):"message": "com.taobao.rigel.rap.model.PsrInfoOutputBean cannot be cast to com.taobao.rigel.rap.model.PsrInfoOutputBean", 原因是這兩個(gè)bean雖然名字一樣,但是類加載器不同,就導(dǎo)致bean的實(shí)際是不一樣的。類是否相同可以用equals進(jìn)行判斷。

因此正確的做法是,先獲取advice返回類型的類加載器,然后加載我們所需要的類,這樣業(yè)務(wù)的代碼就會(huì)認(rèn)得我們的bean了。

???//獲取advice返回類型的類加載器
????ClassLoader?behaviorClassLoader?=?advice.getBehavior().getReturnType().getClassLoader();
????//加載最外層PsrInfoOutputBean
????Class<?>?targetClass?=?behaviorClassLoader.loadClass(ro.getClassNames()[0]);

題外話:

為啥出現(xiàn)了這個(gè)錯(cuò)誤?

出現(xiàn)這個(gè)報(bào)錯(cuò)和開發(fā)的強(qiáng)轉(zhuǎn)類型也有關(guān)系,本地做了個(gè)小測(cè)試,同樣的數(shù)據(jù)。(但咱也沒(méi)發(fā)改開發(fā)的代碼,只能提提建議。 = =)

1、當(dāng)前異常轉(zhuǎn)化:按照開發(fā)業(yè)務(wù)代碼中的list強(qiáng)轉(zhuǎn)對(duì)象

List<Object> list = JSON.*parseArray*(jsonString); PassengerFlightInfo passengerFlightInfo = (PassengerFlightInfo) list.get(0);

這是使用強(qiáng)制類型轉(zhuǎn)換的方式,直接將 list 中的第一個(gè)元素強(qiáng)制轉(zhuǎn)換為 PassengerFlightInfo 對(duì)象。這種方式在編譯時(shí)不會(huì)報(bào)錯(cuò),但如果 list 中的第一個(gè)元素不是 PassengerFlightInfo 對(duì)象,則會(huì)在運(yùn)行時(shí)拋出 ClassCastException 異常。

2、正常轉(zhuǎn)化:優(yōu)化過(guò)后用toJavaObject方法

PassengerFlightInfo passengerFlightInfo = ((JSONObject) list.get(0)).toJavaObject(PassengerFlightInfo.class);: 這是使用 FastJSON 提供的 toJavaObject 方法,將 JSONObject 類型轉(zhuǎn)換為 PassengerFlightInfo 對(duì)象。這種方式在運(yùn)行時(shí)會(huì)檢查轉(zhuǎn)換是否可行,如果 JSONObject 不包含 PassengerFlightInfo 的屬性或結(jié)構(gòu)不匹配,會(huì)拋出異常。這種方式更安全,因?yàn)樗峁┝烁嗟霓D(zhuǎn)換檢查。

推薦使用第二種方式,因?yàn)樗咏押桶踩?#xff0c;能夠更好地處理可能出現(xiàn)的異常情況,并提供更好的錯(cuò)誤信息。

- END -

本文由 mdnice 多平臺(tái)發(fā)布

http://www.risenshineclean.com/news/33072.html

相關(guān)文章:

  • 網(wǎng)站開發(fā)地圖板塊浮動(dòng)青島谷歌優(yōu)化
  • 旅游網(wǎng)站制作百度云網(wǎng)站搜索排名優(yōu)化軟件
  • 定制網(wǎng)站建設(shè)報(bào)價(jià)單網(wǎng)址導(dǎo)航下載到桌面
  • 原創(chuàng)網(wǎng)站模版營(yíng)銷策劃方案模板范文
  • 溫州專業(yè)網(wǎng)站建設(shè)推廣seo信息是什么
  • 南通企業(yè)網(wǎng)頁(yè)制作江西省seo
  • 大連日文網(wǎng)站設(shè)計(jì)營(yíng)銷型網(wǎng)站建設(shè)策劃書
  • 做網(wǎng)站工具免費(fèi)的seo優(yōu)化工具
  • 哪個(gè)網(wǎng)站可以免費(fèi)做H51+x網(wǎng)店運(yùn)營(yíng)推廣
  • 邢臺(tái)做網(wǎng)站建設(shè)優(yōu)化制作公司企業(yè)建站 平臺(tái)
  • 網(wǎng)站推廣什么意思百度搜圖匹配相似圖片
  • 常州網(wǎng)站優(yōu)化營(yíng)銷軟文小短文
  • 怎么注冊(cè)公司教程鄭州seo排名扣費(fèi)
  • 付費(fèi)的網(wǎng)站是指seo網(wǎng)站排名助手
  • 40萬(wàn)用戶自助建站seo根據(jù)什么具體優(yōu)化
  • 手機(jī)端公司網(wǎng)站怎么做seo快速排名優(yōu)化方法
  • 前端后端四川seo整站優(yōu)化
  • iis網(wǎng)站壓縮百度搜索次數(shù)統(tǒng)計(jì)
  • 東營(yíng)建設(shè)信息網(wǎng)公示專業(yè)整站優(yōu)化
  • php模板網(wǎng)站營(yíng)銷推廣計(jì)劃怎么寫
  • ps怎么網(wǎng)站首頁(yè)網(wǎng)店推廣運(yùn)營(yíng)
  • 一浪網(wǎng)站建設(shè)競(jìng)價(jià)網(wǎng)站
  • 網(wǎng)站優(yōu)化吧推廣發(fā)布任務(wù)平臺(tái)app下載
  • 做旅游網(wǎng)站包括哪些欄目成都百度業(yè)務(wù)員電話
  • 大數(shù)據(jù)開發(fā)平臺(tái)seo診斷優(yōu)化方案
  • 芯片設(shè)計(jì)公司重慶 seo
  • 免備案空間哪家好寧波seo服務(wù)推廣
  • 如今做哪些網(wǎng)站致富手機(jī)營(yíng)銷推廣方案
  • 湖北廣域建設(shè)管理有限公司網(wǎng)站北京seo優(yōu)化哪家公司好
  • 廣西十佳旅游景區(qū)網(wǎng)站人多怎么優(yōu)化