摘要:使用的序列化是的,而对于类的反序列化的源码如下这里我们可以清楚地看出来,将读取到的转为然后调用了方法,那么如果我们的属性为空,那么调用函数必然会抛异常,也就产生了之后的结果。补充说明我找到的源码可以看出,对于,,的反序列化均有问题存在。
背景
这是我之前提的问题:问题链接
在使用dubbo 2.5.3的时候,定义的接口中有一个方法使用了实体类作为参数,而这个实体类中定义了一个变量为java.sql.Time类型。不妨暂且定义接口如下:
//BusinessDto中有一个属性dealTime 为java.sql.Time类型 String queryBusiness(BusinessDto param);
当消费者调用这个接口的时候,如果param中的dealTime为null,那么在提供者那里接收到的整个param都为null,如果这个属性不为null,那么参数可以正常的传递。
问题原因解析问题出在反序列化的时候。
dubbo使用的序列化是hession2的,而hession2对于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转为Date然后调用了getTime方法,那么如果我们的dealTime属性为空,那么调用getTime函数必然会抛异常,也就产生了之后的结果。
补充说明我找到的源码可以看出,对于 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 则修复了这个问题,在调用getTime之前做了非空判断,如果为空则把这个属性赋null而不是产生异常。
如果已经开始大规模的使用那么不妨使用别的类型,绕过这三个类型即可避免这个问题。
总结问题来源于同事随口问的一个小问题,挺感兴趣就一直纠缠了下来,发现问题还是挺严重的,另外借用同事的一句话,不再维护的开源软件真的挺危险。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/70074.html
摘要:就是默认的序列化器和反序列化器。最后,那为什么会到这一步呢发现拿到反序列化器后会执行一个操作基本上就到这里了,最主要的原因还是方法,并不是很多博文说的。 首先交代背景,前几天遇到一个小bug,由于其他系统的一个DTO子类和父类有一个字段名重复了,所以导致我set的子类字段那边拿不到值。改起来很简单嘛,让对面把子类的字段删掉就好,但是拿不到值的原因让我想了很久,很明显是序列化和反...
摘要:大揭秘目标了解的新特性,以及版本升级的引导。四元数据改造我们知道以前的版本只有注册中心,注册中心的有数十个的键值对,包含了一个服务所有的元数据。 DUBBO——2.7大揭秘 目标:了解2.7的新特性,以及版本升级的引导。 前言 我们知道Dubbo在2011年开源,停止更新了一段时间。在2017 年 9 月 7 日,Dubbo 悄悄的在 GitHub 发布了 2.5.4 版本。随后,版本...
摘要:当提供程序线程池耗尽时,不能发送到使用者端。一些错误修正动态配置不能删除,支持参数,监控统计问题等新功能支持手册线程池耗尽时自动堆栈转储。在注册表无法连接时被阻止。正常关机,在注册表取消注册和线程池关闭之间增加额外的等待时间。 dubbo分析showImg(https://segmentfault.com/img/bVbam2f?w=1726&h=686); dubbo为什么要对接sp...
摘要:修正了在上的部分修正了比如协议中序列化的问题。配置文件在配置配置在目录下面配置后的工程基本目录结构在项目 杂七杂八的杂 个人博客: 呆萌的程序猿原文:dubbox/dubbo+spring+mybatis+gradle构建REST服务声明:由于sf的编辑自动校验,导致某些英文单词出错,例如:gradle被编辑器自动替换为grade,jdk替换为idk等,查看的时候,请自行翻译。 ---...
摘要:前言到今天为止,正好是工作一年了。一年里有过折磨痛苦,有过成就感,一年后很欣慰能看到自己是有所收获的。自己做出了一件很棒的事情完全可以拿去和别人炫耀,比如你用了一个很好的设计模式,比如你优化了一个功能让他快了倍,比如你开发了一个很棒的工具。 前言 到今天为止,正好是工作一年了。一年里有过折磨痛苦,有过成就感,一年后很欣慰能看到自己是有所收获的。记录如下,如有不当,还望指点。 技术 看...
阅读 3654·2021-11-19 09:56
阅读 1366·2021-09-22 15:11
阅读 1077·2019-08-30 15:55
阅读 3347·2019-08-29 14:02
阅读 2863·2019-08-29 11:07
阅读 402·2019-08-28 17:52
阅读 3140·2019-08-26 13:59
阅读 410·2019-08-26 13:53