JSON (Jackson 1.9.11 および RestTemplate 1.0.1 を使用) をデシリアライズしたいと思います。たとえば、1 つのフィールドがより多くの型の意味を持つ場合があります。
{"responseId":123,"response":"error"}
また
{"responseId":123,"response":{"foo":"bar", ... }}
いずれかのケースが特定のタイプ (文字列またはカスタム Response クラス) の 1 つのセッターで正しく機能しますが、両方のケースを処理できるようにエンティティ Bean のオーバーライドされたセッターに入れると、例外がスローされます。
Caused by: org.springframework.web.client.RestClientException: Could not extract response: no suitable HttpMessageConverter found for response type [xxxx.templates.ExportResponse] and content type [application/json;charset=utf-8]
私は3つの解決策について考えていましたが、どれもうまくいきませんでした:
- 文字列セッターのみを使用し、内部で ObjectMapper を使用してその文字列をアンマーシャリングしますが、それが「エラー」と等しくない場合、その JS 配列が来ると文字列ではないため、文字列セッターは使用されません:(.
- 独自の JsonDeserializer 拡張機能で多相型処理 (@JsonTypeInfo 注釈) を使用します。これを理解し、実装しようとしています。
- HttpMessageConverter のリストを作成し、使用できるすべてのメッセージ コンバーターの中に入れます。しかし、MappingJacksonHttpMessageConverter のみが使用されるため、この手順は不要だと思います。
編集:現在の仕組み
エンティティ Bean のセッター:
@JsonDeserialize(using = ResponseDeserializer.class)
public void setResponse(Object responseObject) {
if(responseObject instanceof Response)
response = (Response) responseObject;
}
ResponseDeserializer の Deserialize メソッド:
public Response deserialize(JsonParser parser, DeserializationContext context) throws IOException, JsonProcessingException {
Response response = new Response();
if(JsonToken.START_OBJECT.equals(parser.getCurrentToken())) {
ObjectMapper mapper = new ObjectMapper();
response = mapper.readValue(parser, Response.class);
} else
throw new JsonMappingException("Unexpected token received.");
return response;
}