考虑以下json,从公共API获取:
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 :(得分:3)
尽管如其他人所指出的那样难以管理,但你可以做你想做的事。添加自定义反序列化器来处理这种情况。我重写了你的bean,因为我觉得你的属性类有点误导。对象中的AttributeEntry类是该&#34;属性中的条目&#34;名单。 ValueObject是表示&#34; key&#34; /&#34; label&#34;的类。宾语。那些bean在下面,但这里是自定义反序列化器。我们的想法是检查JSON中的类型,并根据其&#34;值&#34;实例化相应的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 */
}