jsonrpc4j: How to add type info to parameters?

左心房为你撑大大i 提交于 2020-01-03 17:13:06

问题


I am using jsonrpc4j and got stuck. I made a little example to show my problem:

Abstract class:

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME)
@JsonSubTypes(value = { @JsonSubTypes.Type(value = Walnut.class) })
public abstract class Nut {

}

Concrete subclass:

public class Walnut extends Nut {

}

Interface for the service:

public interface ServiceInterface {
    public Nut getNut();
    public void setNut(Nut nut);
}

The service itself:

public class Service implements ServiceInterface {
    public Nut getNut() { return new Walnut(); }
    public void setNut(Nut nut) {}
}

Server:

JsonRpcServer rpcServer = new JsonRpcServer(new ObjectMapper(), new Service());
StreamServer streamServer = new StreamServer(rpcServer, 50, 1420,
        50, InetAddress.getByName("127.0.0.1"));
streamServer.start();

Client:

JsonRpcClient jsonRpcClient = new JsonRpcClient(new ObjectMapper());
ServiceInterface remoteService = ProxyUtil.createClientProxy(
        ServiceInterface.class.getClassLoader(),
        ServiceInterface.class, jsonRpcClient,
        new Socket(InetAddress.getByName("127.0.0.1"), 1420));

If i call remoteService.getNut() everything works as expected, the log prints:

JSON-PRC Request: {"id":"6064348714687420633","jsonrpc":"2.0","method":"getNut"}
JSON-PRC Response: {"jsonrpc":"2.0","id":"6064348714687420633",
        "result":{"@type":"Walnut"}}

If i call remoteService.setNut(new Walnut()) the server throws an exception, the log prints:

JSON-PRC Request {"id":"9194853851254039397","jsonrpc":"2.0",
        "method":"setNut","params":[{}]}
Error in JSON-RPC Service com.fasterxml.jackson.databind.JsonMappingException:
        Unexpected token (END_OBJECT), expected FIELD_NAME:
        missing property '@type' that is to contain type id  (for class Nut)

The type information of the parameter is missing because the proxy wraps all parameters into one object array (see my last question to understand why the info type is missing in this case).

How can i achieve the desired serialization? I tried to enable default typing and to annotate (with @JsonTypeInfo) the Object.class via mix-in, but both failed (exceptions below).

With enabled default typing [remoteService.getNut(), error on server side]:

Exception while handling request
        com.fasterxml.jackson.databind.JsonMappingException:
        Unexpected token (START_OBJECT), expected START_ARRAY:
        need JSON Array to contain As.WRAPPER_ARRAY type information for
        class com.fasterxml.jackson.databind.JsonNode

With enabled default typing [remoteService.setNut(new Walnut()), error on client side]:

Exception in thread "main" java.lang.IllegalArgumentException:
        Unexpected token (START_ARRAY), expected VALUE_STRING:
        need JSON String that contains type id (for subtype of
        com.fasterxml.jackson.databind.JsonNode)

With mix-in [remoteService.getNut(), error on server side]:

Exception while handling request
        java.lang.IllegalArgumentException:
        Could not resolve type id 'DefaultErrorResolver$ErrorData'
        into a subtype of
        [simple type, class com.fasterxml.jackson.databind.JsonNode]

With mix-in [remoteService.setNut(new Walnut()), error on client side]:

Exception in thread "main" java.lang.ClassCastException:
        [Ljava.lang.Object; cannot be cast to
        com.fasterxml.jackson.databind.JsonNode

Any ideas?


回答1:


I solved my issue by patching the library. Now it serializes all parameters one by one and concatenate them afterwards. Bug report and patch can be found at http://code.google.com/p/jsonrpc4j/issues/detail?id=49.



来源:https://stackoverflow.com/questions/14631502/jsonrpc4j-how-to-add-type-info-to-parameters

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!