2014-12-03 128 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