我正在尝试将某些json字段映射到类实例变量。
我的示例人类如下:
public class Person {
private String name;
private Address address;
//many more fields
//getters and setters
}
示例 Address 类是:
public class Address {
private String street;
private String city;
//many more fields
// getters and setters
}
要反序列化到我的Person类的json对象不包含“地址”字段。看起来像:
{
"name":"Alexander",
"street":"abc 12",
"city":"London"
}
是否有一种方法可以将json反序列化为Person pojo,其中Address字段也已正确映射?
我使用了自定义地址反序列化器,如此处许多文章所述。但是,由于Json对象不包含“地址”字段,因此未调用它。
我已经通过使用JsonNode手动映射每个字段解决了这个问题,但是在我的真实项目中,这不是一个很好的解决方案。
使用杰克逊可以解决此类问题吗? 另外,如果在此之前有人问过这个问题,那么我就此深表歉意,因为我一直在寻找解决方案,但可能还没有看到。
答案 0 :(得分:2)
我认为您这里并不是真正的反序列化问题,而是一个通用的Java问题:如何确保address
字段始终包含一个值。您需要做的就是在address
构造函数中为Person
分配一个默认值,或者在address
方法中为Person.getAddress
生成一个默认值。>
答案 1 :(得分:2)
@JsonUnwrapped
批注。型号:
class Person {
private String name;
@JsonUnwrapped
private Address address;
// getters, setters, toString
}
class Address {
private String street;
private String city;
// getters, setters, toString
}
用法:
ObjectMapper mapper = new ObjectMapper();
String json = "{\"name\":\"Alexander\",\"street\":\"abc 12\",\"city\":\"London\"}";
System.out.println(mapper.readValue(json, Person.class));
打印:
Person{name='Alexander', address=Address{street='abc 12', city='London'}}
有关更多信息,请阅读:
答案 2 :(得分:0)
我了解您的问题,因此有关平面Json的所有Address
字段与Person
处于同一级别。即使事实并非如此,这也可能对您有所帮助。 JsonDeserializer
会很好,但是您需要将其应用于Person
,因为它是所有字段所在的级别。
像这样:
public class CustomDeserializer extends JsonDeserializer<Person> {
// need to use separate ObjectMapper to prevent recursion
// this om will not be registered with this custom deserializer
private final ObjectMapper om;
{
om = new ObjectMapper();
// this is needed because flat json contains unknown fields
// for both types.
om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
}
@Override
public Person deserialize(JsonParser parser, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
// make a string of json tree so not any particular object
String json = om.readTree(parser).toString();
// deserialize it as person (ignoring unknown fields)
Person person = om.readValue(json, Person.class);
// set address deserializing it from teh same string, same manner
person.setAddress(om.readValue(json, Address.class));
return person;
}
}
当然,这不是唯一的方法,也可能没有最佳的性能,它仅与如何在自定义解串器中进行反序列化有关。如果您的Person
和Address
对象具有10个字段,那么每个使用此字段都不会有问题。
更新
我认为在您的情况下-根据您的示例数据-Michał Ziober's
answer可能是最好的,但是如果您需要比普通拆包更复杂的数据处理,则只需反序列化Person
类就像我介绍的那样。