2012-12-15 63 views
6

我想反序列化JSON(傑克遜1.9.11和RestTemplate 1.0.1),其中,一個字段可以具有多種類型的含義,例如:反序列化JSON利用多種類型的在一個場

{"responseId":123,"response":"error"} 

{"responseId":123,"response":{"foo":"bar", ... }} 

無論一種或另一種情況下,用特定的類型(字符串OD定製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] 

我在想三種解決方案,但我沒有得到任何人的工作:只使用字符串setter和內部使用ObjectMapper來解讀該字符串

  • ,如果它不等於「錯誤」 ,但是當那個JS數組來的時候,它不是字符串,所以沒有使用String setter :(。
  • 使用具有自己的JsonDeserializer擴展的多態類型處理(@JsonTypeInfo註釋) - 我仍然試圖理解這一點並實現。
  • 創建HttpMessageConverter的列表並放入所有消息轉換器中,我可以使用。但我這一步是不必要的,因爲只有MappingJacksonHttpMessageConverter被使用了,對嗎?

編輯:它是如何工作的,現在

二傳手在實體bean:

@JsonDeserialize(using = ResponseDeserializer.class) 
public void setResponse(Object responseObject) { 
    if(responseObject instanceof Response) 
     response = (Response) responseObject; 
} 

Deserialize方法在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

我建議你使用傑克遜解析器服務器端操縱JSON對象 –

+0

我在客戶端工作,服務器不是我的業務:( – shmoula

回答

7

實現這一點的唯一方法是使用一個自定義解串器。

下面是一個例子:

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 

} 
+0

我同意,我試圖做一些類似的方式,因爲我寫了(用@JsonDeserialize(使用= ResponseDataDeserializer.class) ),所以如果我得到它運行,我會標記你的答案:) – shmoula

+0

好吧,它的工作方式,附加到原始問題的工作代碼。謝謝。 – shmoula