问题
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