2014-12-03 91 views
0

我收到的數據在JSON自定義反序列化JSON傑克遜排除invalide陣列

{ 
"status": "INVALID_DATA", 
"errors":{ "invalid_id": "Id isn't available", 
      ... 
      "wrong_address": "Address error msg" 
     } 
} 

按鍵及數量結構「錯誤」對我來說是未知的。我試圖用類映射此

@JsonIgnoreProperties(ignoreUnknown = true) 
public class StatusErrors 
{ 
    private String status; 
    private HashMap<String, String> errors = new HashMap<String, String>(); 

    public String getStatus() { 
     return status; 
    } 

    public void setStatus(String status) { 
     this.status = status; 
    } 

    public HashMap<String, String> getErrors() { 
     return errors; 
    } 

    public void setErrors(HashMap<String, String> errors) { 
     this.errors = errors; 
    } 
} 

它工作正常,如果我有「錯誤」,但是當服務器說「OK」,並沒有任何錯誤,它給我

{ 
"status": "OK", 
"errors":[] 
} 

(唐」請問我是誰寫的服務器) 所以映射器崩潰。 我想寫一個自定義的JsonDeserializer(通用方法)

public abstract class ExcludeEmptyArrayDeserializer<T> extends JsonDeserializer<T> { 

    private final Class<T> clazz; 

    protected ExcludeEmptyArrayDeserializer(Class<T> clazz) { 
     this.clazz = clazz; 
    } 

    @Override 
    public T deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { 
     ObjectCodec oc = jp.getCodec(); 
     JsonNode node = oc.readTree(jp); 

     if(node.has("errors")) { 
      if (node.get("errors").isArray() && !node.get("errors").getElements().hasNext()) 
       ((ObjectNode)node).remove("errors"); 
     } 

     ObjectMapper objectMapper = new ObjectMapper(); 
     return objectMapper.readValue(node, clazz); // doesn't work 
     //return oc.treeToValue(node, clazz); // doesn't work too 
    } 
} 

public class StatusErrorsDeserializer extends ExcludeEmptyArrayDeserializer<StatusErrors> { 
    public StatusErrorsDeserializer() { 
     super(StatusErrors.class); 
    } 
} 

結果使用代碼有一個觀點

SimpleModule module = new SimpleModule("", Version.unknownVersion()); 
    module.addDeserializer(StatusErrors.class, new StatusErrorsDeserializer()); 

    ObjectMapper mapper = new ObjectMapper().setVisibility(JsonMethod.FIELD, JsonAutoDetect.Visibility.ANY).withModule(module); 
    MappingJacksonHttpMessageConverter messageConverter = new MappingJacksonHttpMessageConverter(); 
    messageConverter.setObjectMapper(mapper); 

    getRestTemplate().getMessageConverters().clear(); 
    getRestTemplate().getMessageConverters().add(messageConverter); 

「錯誤」節點正確刪除,但這個解決方案仍然無法正常工作。 我想我在JsonDeserializer.deserialize方法中犯了一個錯誤,但沒有想法。

BTW StatusErrors類可以是來自服務器的其他複雜消息的基類。

回答

1

最簡單的解決辦法是改變錯誤的變量聲明爲Object:

@JsonIgnoreProperties(ignoreUnknown = true) 
class StatusErrors { 
    private String status; 
    private Object errors; 
    public Map<String, String> getErrorsMap() { 
     if (this.errors instanceof Map) { 
      return (Map)this.errors; 
     } 
     return null; 
    } 
.... 

你不需要任何串行器和解串器:

ObjectMapper objectMapper = new ObjectMapper(); 

StatusErrors result1 = objectMapper.readValue(JSON1, StatusErrors.class); 
System.out.println(result1); 
System.out.println(result1.getErrors().getClass()); 
System.out.println(result1.getErrorsMap()); 
StatusErrors result2 = objectMapper.readValue(JSON2, StatusErrors.class); 
System.out.println(result2); 

上面的代碼將打印:

StatusErrors(status=INVALID_DATA, errors={invalid_id=Id isn't available, wrong_address=Address error msg}) 
class java.util.LinkedHashMap 
{invalid_id=Id isn't available, wrong_address=Address error msg} 
StatusErrors(status=OK, errors=[]) 
+0

你已經清除了我的視野,男人。謝謝。 – 2014-12-04 17:49:16