Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

motan泛化调用不支持List<T>类型 #1042

Open
coderDylan opened this issue Sep 3, 2023 · 2 comments
Open

motan泛化调用不支持List<T>类型 #1042

coderDylan opened this issue Sep 3, 2023 · 2 comments

Comments

@coderDylan
Copy link

motan支持POJO作为参数的情况,例如:
User rename(User user, String name) throws Exception;
通过定义Map作为参数,并指定POJO全限定名时,可以正常完成泛化调用,服务端反序列化正常的,代码如下:
CommonClient service = referer.getRef(); Map<String, Object> person = new HashMap<String, Object>(); person.put("name", "xxx"); person.put("id", 999); Request request = MotanClientUtil.buildRequest("com.weibo.motan.demo.service.MotanDemoService", "rename", "com.weibo.motan.demo.service.model.User,java.lang.String", new Object[]{person,"dinglang"}, null); service.call(request, Object.class);

但是,当参数是List类型时,服务端反序列化正常,但因为T缺失,所以无法完成泛化调用。例如:
void batchSave(List list);
这种情况下,传递的参数是ArrayList,指定的参数类型是"java.util.List",调用代码如下:
` CommonClient client = referer.getRef();

    Map<String, Object> person = new HashMap<String, Object>();
    person.put("name", "xxx");
    person.put("id", 999);

    Map<String, Object> user = new HashMap<String, Object>();
    user.put("name", "yyy");
    user.put("id", 110);

    List<Object> list = new ArrayList<>();
    list.add(person);
    list.add(user);

    Request request2 = MotanClientUtil.buildRequest("com.weibo.motan.demo.service.MotanDemoService", "batchSave", "java.util.List", new Object[]{list}, null);
    client.call(request2, Object.class);`

这种,会导致服务端com.weibo.api.motan.rpc.DefaultProvider#invoke这里最终调用Impl实现失败。
com.weibo.api.motan.transport.ProviderMessageRouter#processLazyDeserialize这里反序列化是正常的,不过因为反序列化出来的结果是List,而实际方法是List list,所以最终无法成功调用

@coderDylan
Copy link
Author

@rayzhang0603 这个问题现在有解吗?Dubbo是可以直接这样调用的

@rayzhang0603
Copy link
Collaborator

Motan框架并没有对泛化调用做特别支持,上面case中的map方式可以调用成功是hessian2序列化提供的能力。

Motan中的CommonClient的设计意图是方便跨语言调用,其他语言提供的服务在java侧并不会有对应的service,这时就可以使用CommonClient来进行调用。 不同语言间的数据传递主要依赖不同序列化方式。比如使用ProtoBuf或者Breeze序列化

Motan没有支持泛型主要是基于下面考虑:

  1. 泛化只能解决简单对象的无依赖调用,实际业务使用的复杂对象很难用泛化来描述
  2. 泛化一般与使用的序列化实现相关,泛化能力也很难在多语言中达成能力一致。
  3. java的泛化通过反射来实现,对于不需要使用泛化的场景会增加额外的性能开销。
  4. 泛化会破坏RPC强契约的形式,容易让client侧和server侧对接口、对象的维护变得困难,除了一些通用服务测试场景外,基本也没有什么使用泛化的场景。而通用测试场景可以通过流量录制回放方式,直接在二进制流方面进行处理,效率比泛化会更高,不过对二次开发能力要求较高。
  5. 如果泛化的目的是为了与其他语言交互,建议通过ProtoBuf或者Breeze这些强契约的方式来实现,更适合服务的长期维护。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants