我想反序列化JSON(使用Jackson 1.9.11和RestTemplate 1.0.1),其中一个字段可能具有更多类型含义,例如:
{"responseId":123,"response":"error"}
要么
{"responseId":123,"response":{"foo":"bar", ... }}
一个或另一种情况对于一个特定类型的设置器(String od custom Response类)都可以正常工作,但是当我将实体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]
我当时在考虑三种解决方案,但没有任何一种可行:
实体Bean中的二传手:
@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; }
实现此目标的唯一方法是使用自定义解串器。
这是一个例子:
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 }