2016-12-01 41 views
0

考虑以下JSON,从公共API获取:Json的反序列化中的Java/w的混合类型的杰克逊,包含在一个阵列

anyObject : { 
    attributes: [ 
        { 
         "name":"anyName", 
         "value":"anyValue" 
        }, 
        { 
         "name":"anyName", 
         "value": 
         { 
          "key":"anyKey", 
          "label":"anyLabel" 
         } 
        } 
       ] 
       } 

正如你所看到的,有时值是一个简单的字符串,有时它的一个对象。是它在某种程度上可能与反序列化JSON样,结果的,喜欢的东西:

class AnyObject { 
    List<Attribute> attributes; 
} 

class Attribute { 
    private String key; 
    private String label; 
} 

我将如何设计我的模型涵盖两种情况。那可能吗 ?

+0

简短的回答,是的如果你修复你的JSON。取决于你将使用的框架。 – Mena

+0

正如我已经提到的,我从一个公共的API获取这个,所以我无法修复JSON。 – lunatikz

+0

你刚刚做到了。键值对用'='符号分隔,这将暗示一个不可解析的JSON,在您编辑之后这些JSON不见了。 – Mena

回答

1

尽管很难像其他人指出的那样管理,你可以做你想做的事。添加一个自定义的反序列化器来处理这种情况。我重写了你的beans,因为我觉得你的Attribute类有点误导。该属性中的AttributeEntry类是该“attributes”列表中的一个条目。 ValueObject是代表“key”/“label”对象的类。那些bean在下面,但是这里是自定义的解串器。这个想法是检查JSON中的类型,并根据其“值”类型实例化适当的AttributeEntry。

public class AttributeDeserializer extends JsonDeserializer<AttributeEntry> { 
    @Override 
    public AttributeEntry deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException { 
     JsonNode root = p.readValueAsTree(); 
     String name = root.get("name").asText(); 
     if (root.get("value").isObject()) { 
      // use your object mapper here, this is just an example 
      ValueObject attribute = new ObjectMapper().readValue(root.get("value").asText(), ValueObject.class); 
      return new AttributeEntry(name, attribute); 
     } else if (root.get("value").isTextual()) { 
      String stringValue = root.get("value").asText(); 
      return new AttributeEntry(name, stringValue); 
     } else { 
      return null; // or whatever 
     } 
    } 
} 

因为这种暧昧型不便,你将不得不做一些类型的整个代码库检查。

然后,您可以添加此自定义解串器到你的对象映射器,像这样:

ObjectMapper objectMapper = new ObjectMapper(); 
SimpleModule simpleModule = new SimpleModule(); 
simpleModule.addDeserializer(AttributeEntry.class, new AttributeDeserializer()); 
objectMapper.registerModule(simpleModule); 

这里的AttributeEntry:

public class AttributeEntry { 
    private String name; 
    private Object value; 

    public AttributeEntry(String name, String value) { 
     this.name = name; 
     this.value = value; 
    } 

    public AttributeEntry(String name, ValueObject attributes) { 
     this.name = name; 
     this.value = attributes; 
    } 
    /* getters/setters */ 
} 

这里的的ValueObject:

public class ValueObject { 
    private String key; 
    private String label; 
    /* getters/setters */ 
}