摘要:使用的序列化是的,而對(duì)于類的反序列化的源碼如下這里我們可以清楚地看出來,將讀取到的轉(zhuǎn)為然后調(diào)用了方法,那么如果我們的屬性為空,那么調(diào)用函數(shù)必然會(huì)拋異常,也就產(chǎn)生了之后的結(jié)果。補(bǔ)充說明我找到的源碼可以看出,對(duì)于,,的反序列化均有問題存在。
背景
這是我之前提的問題:問題鏈接
在使用dubbo 2.5.3的時(shí)候,定義的接口中有一個(gè)方法使用了實(shí)體類作為參數(shù),而這個(gè)實(shí)體類中定義了一個(gè)變量為java.sql.Time類型。不妨?xí)呵叶x接口如下:
//BusinessDto中有一個(gè)屬性dealTime 為java.sql.Time類型 String queryBusiness(BusinessDto param);
當(dāng)消費(fèi)者調(diào)用這個(gè)接口的時(shí)候,如果param中的dealTime為null,那么在提供者那里接收到的整個(gè)param都為null,如果這個(gè)屬性不為null,那么參數(shù)可以正常的傳遞。
問題原因解析問題出在反序列化的時(shí)候。
dubbo使用的序列化是hession2的,而hession2對(duì)于Time類的反序列化的源碼如下:
static class SqlTimeFieldDeserializer extends FieldDeserializer { private final Field _field; SqlTimeFieldDeserializer(Field field) { _field = field; } void deserialize(AbstractHessianInput in, Object obj) throws IOException { java.sql.Time value = null; try { java.util.Date date = (java.util.Date) in.readObject(); value = new java.sql.Time(date.getTime()); _field.set(obj, value); } catch (Exception e) { logDeserializeError(_field, obj, value, e); } } }
這里我們可以清楚地看出來,將in讀取到的object轉(zhuǎn)為Date然后調(diào)用了getTime方法,那么如果我們的dealTime屬性為空,那么調(diào)用getTime函數(shù)必然會(huì)拋異常,也就產(chǎn)生了之后的結(jié)果。
補(bǔ)充說明我找到的源碼可以看出,對(duì)于 java.sql.Date, java.sql.Timestamp, java.sql.Time的反序列化均有問題存在。
static class SqlDateFieldDeserializer extends FieldDeserializer { private final Field _field; SqlDateFieldDeserializer(Field field) { _field = field; } void deserialize(AbstractHessianInput in, Object obj) throws IOException { java.sql.Date value = null; try { java.util.Date date = (java.util.Date) in.readObject(); value = new java.sql.Date(date.getTime()); _field.set(obj, value); } catch (Exception e) { logDeserializeError(_field, obj, value, e); } } } static class SqlTimestampFieldDeserializer extends FieldDeserializer { private final Field _field; SqlTimestampFieldDeserializer(Field field) { _field = field; } void deserialize(AbstractHessianInput in, Object obj) throws IOException { java.sql.Timestamp value = null; try { java.util.Date date = (java.util.Date) in.readObject(); value = new java.sql.Timestamp(date.getTime()); _field.set(obj, value); } catch (Exception e) { logDeserializeError(_field, obj, value, e); } } } static class SqlTimeFieldDeserializer extends FieldDeserializer { private final Field _field; SqlTimeFieldDeserializer(Field field) { _field = field; } void deserialize(AbstractHessianInput in, Object obj) throws IOException { java.sql.Time value = null; try { java.util.Date date = (java.util.Date) in.readObject(); value = new java.sql.Time(date.getTime()); _field.set(obj, value); } catch (Exception e) { logDeserializeError(_field, obj, value, e); } } }
而hessian4 則修復(fù)了這個(gè)問題,在調(diào)用getTime之前做了非空判斷,如果為空則把這個(gè)屬性賦null而不是產(chǎn)生異常。
如果已經(jīng)開始大規(guī)模的使用那么不妨使用別的類型,繞過這三個(gè)類型即可避免這個(gè)問題。
總結(jié)問題來源于同事隨口問的一個(gè)小問題,挺感興趣就一直糾纏了下來,發(fā)現(xiàn)問題還是挺嚴(yán)重的,另外借用同事的一句話,不再維護(hù)的開源軟件真的挺危險(xiǎn)。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/70074.html
摘要:就是默認(rèn)的序列化器和反序列化器。最后,那為什么會(huì)到這一步呢發(fā)現(xiàn)拿到反序列化器后會(huì)執(zhí)行一個(gè)操作基本上就到這里了,最主要的原因還是方法,并不是很多博文說的。 ????首先交代背景,前幾天遇到一個(gè)小bug,由于其他系統(tǒng)的一個(gè)DTO子類和父類有一個(gè)字段名重復(fù)了,所以導(dǎo)致我set的子類字段那邊拿不到值。改起來很簡單嘛,讓對(duì)面把子類的字段刪掉就好,但是拿不到值的原因讓我想了很久,很明顯是序列化和反...
摘要:大揭秘目標(biāo)了解的新特性,以及版本升級(jí)的引導(dǎo)。四元數(shù)據(jù)改造我們知道以前的版本只有注冊(cè)中心,注冊(cè)中心的有數(shù)十個(gè)的鍵值對(duì),包含了一個(gè)服務(wù)所有的元數(shù)據(jù)。 DUBBO——2.7大揭秘 目標(biāo):了解2.7的新特性,以及版本升級(jí)的引導(dǎo)。 前言 我們知道Dubbo在2011年開源,停止更新了一段時(shí)間。在2017 年 9 月 7 日,Dubbo 悄悄的在 GitHub 發(fā)布了 2.5.4 版本。隨后,版本...
摘要:當(dāng)提供程序線程池耗盡時(shí),不能發(fā)送到使用者端。一些錯(cuò)誤修正動(dòng)態(tài)配置不能刪除,支持參數(shù),監(jiān)控統(tǒng)計(jì)問題等新功能支持手冊(cè)線程池耗盡時(shí)自動(dòng)堆棧轉(zhuǎn)儲(chǔ)。在注冊(cè)表無法連接時(shí)被阻止。正常關(guān)機(jī),在注冊(cè)表取消注冊(cè)和線程池關(guān)閉之間增加額外的等待時(shí)間。 dubbo分析showImg(https://segmentfault.com/img/bVbam2f?w=1726&h=686); dubbo為什么要對(duì)接sp...
摘要:修正了在上的部分修正了比如協(xié)議中序列化的問題。配置文件在配置配置在目錄下面配置后的工程基本目錄結(jié)構(gòu)在項(xiàng)目 雜七雜八的雜 個(gè)人博客: 呆萌的程序猿原文:dubbox/dubbo+spring+mybatis+gradle構(gòu)建REST服務(wù)聲明:由于sf的編輯自動(dòng)校驗(yàn),導(dǎo)致某些英文單詞出錯(cuò),例如:gradle被編輯器自動(dòng)替換為grade,jdk替換為idk等,查看的時(shí)候,請(qǐng)自行翻譯。 ---...
摘要:前言到今天為止,正好是工作一年了。一年里有過折磨痛苦,有過成就感,一年后很欣慰能看到自己是有所收獲的。自己做出了一件很棒的事情完全可以拿去和別人炫耀,比如你用了一個(gè)很好的設(shè)計(jì)模式,比如你優(yōu)化了一個(gè)功能讓他快了倍,比如你開發(fā)了一個(gè)很棒的工具。 前言 到今天為止,正好是工作一年了。一年里有過折磨痛苦,有過成就感,一年后很欣慰能看到自己是有所收獲的。記錄如下,如有不當(dāng),還望指點(diǎn)。 技術(shù) 看...
閱讀 3746·2021-11-19 09:56
閱讀 1567·2021-09-22 15:11
閱讀 1225·2019-08-30 15:55
閱讀 3434·2019-08-29 14:02
閱讀 3047·2019-08-29 11:07
閱讀 497·2019-08-28 17:52
閱讀 3235·2019-08-26 13:59
閱讀 494·2019-08-26 13:53