dubbo客户端通过rpc调用dubbo 服务的时出现参数丢失的问题

本文详细描述了在服务B通过RPC调用服务A的Dubbo接口时,遇到参数丢失的问题。现象表现为服务A接收到的参数与服务B传递的不一致。经过排查,问题根源在于子类和父类存在同名字段,导致Hessian序列化与反序列化过程中出现问题。解决办法包括避免子类与父类同名属性、更换或修改Hessian版本,以及使用Java原生序列化。文章提供了问题重现的测试代码和序列化、反序列化的分析过程。
摘要由CSDN通过智能技术生成

现象

服务A提供一个dubbo接口,LoginServer.login(LoginReqDTO reqDTO);
服务B通过rpc调用A提供的LoginService接口的login方法。查看日志发现服务B发起调用时传递的reqDTO参数与服务A接收到的参数部分不一致。

  1. 例如:服务B请求参数
reqDTO=LoginReqDTO(appKey="appKey", mobile="18812345678", countryCallingCode="+86",password="a12345")
  1. 服务A接受参数:
reqDTO=LoginReqDTO(appKey="appKey", mobile=null, countryCallingCode=null,password="a12345")

解决思路

  1. 服务A和服务B的版本不一致,导致接口调用时参数传递出错。排查后不是该原因
  2. LoginReqDTO中的某些属性没有get和set方法。排查后不是该原因
  3. 经过与其他可以获取到的参数进行对比发现:该字段相较于其它字段较特殊的地方是子类和父类有相同的字段,去掉继承,发现字段能够顺利传递过去了。(问题的根本点终于找到了
@Data
public class LoginReqDTO extends BaseReq{
   
	private String mobile;                // 父类已存在,子类重复定义
	private String countryCallingCode;   // 父类已存在,子类重复定义
	private String password;
	......
}

@Data
public class BaseReq{
   
	private String appKey;
	private String mobile;
	private String countryCallingCode;
}

解决办法

  1. 避免在子类中出现与父类同名的属性:比较简单,但是在一个大的团队中协同开发时,无法避免。
  2. 找一个没有BUG得HESSION版本或者自己动手改改代码重新打个包

相对简单的改法是:在出现同名时,如果子类中已经有了,那么父类中对应属性直接忽略,代码量很少,只需要加一个 continue 即可,但是这样改容易挖坑。

  1. 直接用Java原生的序列化方法(最笨的一个解决办法):
B obj = new B();
obj.setA(0);
// 序列化
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
objectOutputStream.writeObject(obj);
// 反序列化
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
obj = (B
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值