4

私はjsonrpc4jを使用していますが、行き詰まりました。私の問題を示すために小さな例を作りました:

抽象クラス:

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

}

具体的なサブクラス:

public class Walnut extends Nut {

}

サービスのインターフェース:

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

サービス自体:

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

サーバ:

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

クライアント:

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));

remoteService.getNut()を呼び出すと、すべてが期待どおりに機能し、ログが出力されます。

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

remoteService.setNut(new Walnut())を呼び出すと、サーバーが例外をスローし、ログが出力されます。

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)

プロキシはすべてのパラメーターを 1 つのオブジェクト配列にラップするため、パラメーターの型情報が欠落しています (この場合に情報の型が欠落している理由を理解するには、最後の質問を参照してください)。

目的のシリアライゼーションを達成するにはどうすればよいですか? デフォルトの入力を有効にして、ミックスインを介してObject.classに (@JsonTypeInfo で) 注釈を付けようとしましたが、両方とも失敗しました (以下の例外)。

デフォルトの入力が有効になっている場合 [ remoteService.getNut()、サーバー側でエラー]:

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

デフォルトの入力が有効になっている場合 [ remoteService.setNut(new Walnut())、クライアント側でエラー]:

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)

mix-in [ remoteService.getNut()、サーバー側のエラー]:

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]

mix-in [ remoteService.setNut(new Walnut())、クライアント側でエラー]:

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

何か案は?

4

1 に答える 1

6

ライブラリにパッチを適用することで問題を解決しました。すべてのパラメーターを 1 つずつシリアル化し、後で連結します。バグ レポートとパッチはhttp://code.google.com/p/jsonrpc4j/issues/detail?id=49にあります。

于 2013-02-01T12:28:58.353 に答える