将 Json 字段包装到 pojo 的实例变量中

我正在尝试将某些 json 字段映射到类实例变量。


我的示例Person类如下所示:


public class Person {

   private String name;

   private Address address;


   //many more fields 


   //getters and setters

}

示例地址类是:


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?


我使用了一个自定义地址反序列化器,正如这里很多帖子中提到的那样。但是,它没有被调用,因为 Json 对象不包含“地址”字段。


我已经通过使用 JsonNode 手动映射每个字段来解决这个问题,但是在我的实际项目中,这不是一个好的解决方案。


使用杰克逊是否有解决此类问题的方法?另外,如果之前有人问过这个问题,那么代表我道歉,因为我已经深入寻找解决方案并且可能还没有看到它。.


万千封印
浏览 102回答 3
3回答

慕尼黑5688855

@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'}}

缥缈止盈

我不认为您在这里真的有反序列化问题,而是一般的 Java 问题:如何确保该address字段始终包含一个值。您需要做的就是address在构造函数中分配一个默认值,或者在方法中Person生成并分配一个默认值。addressPerson.getAddress

慕斯709654

我理解你的问题,所以它是关于平面 Json 的,它的所有Address字段都与Person. 即使不完全如此,这也可能对您有所帮助。JsonDeserializer会很好,但你需要应用它,Person因为它是所有字段所在的级别。所以像这样:public class CustomDeserializer extends JsonDeserializer<Person> {&nbsp; &nbsp; // need to use separate ObjectMapper to prevent recursion&nbsp; &nbsp; // this om will not be registered with this custom deserializer&nbsp; &nbsp; private final ObjectMapper om;&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; om = new ObjectMapper();&nbsp; &nbsp; &nbsp; &nbsp; // this is needed because flat json contains unknown fields&nbsp; &nbsp; &nbsp; &nbsp; // for both types.&nbsp; &nbsp; &nbsp; &nbsp; om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);&nbsp; &nbsp; }&nbsp; &nbsp; @Override&nbsp; &nbsp; public Person deserialize(JsonParser parser, DeserializationContext ctxt)&nbsp; &nbsp; &nbsp; &nbsp; throws IOException, JsonProcessingException {&nbsp; &nbsp; &nbsp; &nbsp; // make a string of json tree so not any particular object&nbsp; &nbsp; &nbsp; &nbsp; String json = om.readTree(parser).toString();&nbsp; &nbsp; &nbsp; &nbsp; // deserialize it as person (ignoring unknown fields)&nbsp; &nbsp; &nbsp; &nbsp; Person person = om.readValue(json, Person.class);&nbsp; &nbsp; &nbsp; &nbsp; // set address deserializing it from teh same string, same manner&nbsp; &nbsp; &nbsp; &nbsp; person.setAddress(om.readValue(json, Address.class));&nbsp; &nbsp; &nbsp; &nbsp; return person;&nbsp; &nbsp; }}当然,这不是唯一的方法,也可能没有最好的性能,但这只是关于如何在自定义反序列化器中进行反序列化。如果您的Person&Address对象有 10 个字段,每个字段都使用这应该不是问题。更新我认为在您的情况下 - 基于您的示例数据 - Michał Ziober 的答案可能是最好的,但如果您需要比简单展开数据更复杂的处理,您只需要Person像我介绍的那样以某种方式反序列化类。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java