10

「 Jackson動的プロパティ名」という質問はすでに見ましたが、私の質問には実際には答えていません。

私はこのようなものをデシリアライズしたい:

public class Response<T> {
    private String status;
    private Error error;
    private T data;
}

ただし、異なるサービスが存在し、いくつかの異なるデータで同じ構造を返すため、データには異なる名前を付けることができます。たとえば、'user' と 'contract' :

{
  response: {
    status: "success",
    user: {
        ...
    }
  }
}

また

{
  response: {
    status: "failure",
    error : {
        code : 212, 
        message : "Unable to retrieve contract"
    }
    contract: {
        ...
    }
  }
}

次のように応答オブジェクトを一般化したいと思います。

public class UserResponse extends Response<User> {}

私は次のことを試しましたが、それが私のユースケースであるかどうか、または良い方法で使用しないかどうかはわかりません:

 @JsonTypeInfo(include = As.WRAPPER_OBJECT, use = Id.CLASS)
 @JsonSubTypes({@Type(value = User.class, name = "user"),
                    @Type(value = Contract.class, name = "contract")})

最後に、カスタム デシリアライザーを作成しました。それは動作しますが、私は満足していません:

public class ResponseDeserializer extends JsonDeserializer<Response> {
@Override
public Response deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
    ObjectMapper mapper = new ObjectMapper();
    Response responseData = new Response();
    Object data = null;

    for (; jp.getCurrentToken() != JsonToken.END_OBJECT; jp.nextToken()) {
        String propName = jp.getCurrentName();
        // Skip field name:
        jp.nextToken();

        if ("contract".equals(propName)) {
            data = mapper.readValue(jp, Contract.class);
        } else if ("user".equals(propName)) {
            data = mapper.readValue(jp, User.class);
        } else if ("status".equals(propName)) {
            responseData.setStatus(jp.getText());
        } else if ("error".equals(propName)) {
            responseData.setError(mapper.readValue(jp, com.ingdirect.dg.business.object.community.api.common.Error.class));
        }
    }

    if (data instanceof Contract) {
        Response<Contract> response = new Response<Ranking>(responseData);
        return response;
    }

    if (data instanceof User) {
        Response<User> response = new Response<User>(responseData);
        return response;
    }

    // in all other cases, the type is not yet managed, add it when needed
    throw new JsonParseException("Cannot parse this Response", jp.getCurrentLocation());
}

}

注釈でこれをきれいにするアイデアはありますか? 前もって感謝します !

4

2 に答える 2

0

やってみました:

public class AnyResponse {
    private String status;
    private Error error;
    private Contract contract;
    private User user;
    // And all other possibilities.
}
// ...
mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);

これにより、JSON に表示されるすべてのオブジェクトが埋められ、残りは null のままになります。

次に、関連するオブジェクトを Response に入力できます。

于 2013-09-13T13:32:27.703 に答える