Jackson 复杂对象反序列化为 LinkedHashMap

1、情景描述

Jackson 复杂对象反序列化为 LinkedHashMap_第1张图片

1. 客户端向网关发起 HTTP POST 请求,Content-Type = application/json,消息体为:

{
    "custid": "client",           // 应用id
    "appid": "sdeserver",         // 服务端id
    "bean": "sdeBean",            
    "method": "sign",
    "args": "[InputParam]"        // InputParam 对象
}

2. 网关接受到请求,通过请求 Body 中的 appid(远程服务在 Zookeeper 中注册的 名称),获取远程服务调用信息(ip + port),然后使用 Netty,与远程服务建立连接,将调用信息发送给 远程服务。

3. 远程服务通过反射,获取 bean 对应的类,使用MethodInvoker ,获取对应的方法。在获取方法时报错:

        java.lang.NoSuchMethodException: com.sde.auth.beans.SdeBean.sign(java.util.LinkedHashMap)

       从错误信息中可以看出,原本 SdeBean.sign(InputParam),实际传入的是 LinkedHashMap.

2、错误原因

        客户端在序列化 InputParam 对象,作为请求体发送后,网关 controller 层反序列化后,InputParam对象被反序列化为了LinkedHashMap对象,因此导致远程服务找不到该方法,报错。

3、解决办法

        由于公司接口不支持自定义类的远程调用,因此未做修改。

        对于这种情况,可以使用 ObjectMapper 类的 convertValue(Object fromValue, Class toValue) 进行转换:

ObjectMapper mapper = new ObjectMapper();
InputParam inputParam = mapper.convertValue(args[0], InputParam.class);

        但是前题是明确知道需要转为的类型。由于网关只是做转发相关逻辑,不包含具体类信息,因此不适合本文的场景。如果需要解决,需要在传递给服务端的数据中,加上具体的类型信息,在RPC服务端进行转换。

4、参考

https://blog.csdn.net/qq_27088383/article/details/79819803

https://stackoverflow.com/questions/15430715/casting-linkedhashmap-to-complex-object?r=SearchResults#

你可能感兴趣的:(Java,RPC)