我想反序列化JSON(使用Jackson 1.9.11和RestTemplate 1.0.1),其中一个字段可能具有更多类型含义,例如:
{"responseId":123,"response":"error"}
或
{"responseId":123,"response":{"foo":"bar", ... }}
任何一个或其他案例都可以使用一个特定类型的setter(String od自定义Response类)正常工作,但是当我放入我的实体bean覆盖setter以便能够处理这两种情况时,抛出异常:
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]
我在考虑三种解决方案,但我没有让它们工作:
实体bean中的Setter:
@JsonDeserialize(using = ResponseDeserializer.class)
public void setResponse(Object responseObject) {
if(responseObject instanceof Response)
response = (Response) responseObject;
}
在ResponseDeserializer中反序列化方法:
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;
}
答案 0 :(得分:11)
实现这一目标的唯一方法是使用自定义反序列化器。
以下是一个例子:
ObjectMapper mapper = new ObjectMapper();
SimpleModule testModule = new SimpleModule("MyModule", new Version(1, 0, 0, null));
testModule.addDeserializer(Response.class, new ResponseJsonDeserializer());
mapper.registerModule(testModule);
以下是如何编写(至少如何编写)反序列化器:
class ResponseJsonDeserializer extends JsonDeserializer<Response> {
@Override
public Responsedeserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
Response response = new Response();
if(jp.getCurrentToken() == JsonToken.VALUE_STRING) {
response.setError(jp.getText());
} else {
// Deserialize object
}
return response;
}
}
class Response {
private String error;
private Object otherObject; // Use the real type of your object
public boolean isError() {
return error != null;
}
// Getters and setters
}