包装的Json田成POJO的实例变量

问题描述 投票:2回答:3

我试图映射某些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
}

JSON对象进行反序列化到我的Person类不包含“地址”字段。看起来像:

{
"name":"Alexander",
"street":"abc 12",
"city":"London"
}

有没有一种方法来反序列化JSON的到Person POJO所在地址字段也映射是否正确?

我已经使用了自定义地址解串器在那么多帖子略。然而,它没有被称为JSON对象不包含“地址”字段。

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

是否有任何变通使用杰克逊这样的问题?另外,如果这个问题已经那么作为我进行了深入的搜索解决方案,并有可能没有看到它代表我的道歉之前已经问。 。

java json spring jackson jackson2
3个回答
3
投票

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

欲了解更多信息阅读:

  1. Jackson Annotation Examples
  2. Annotation Type JsonUnwrapped
  3. Jackson JSON - Using @JsonUnwrapped to serialize/deserialize properties as flattening data structure

2
投票

我不认为你真的有一个反序列化的问题就在这里,而是一个普通的Java问题:如何确保address字段总是包含一个值。所有你需要做的是要么分配addressPerson构造函数的默认值,或生成并在address方法Person.getAddress指定一个默认值。


0
投票

我明白你的问题,所以它是具有在同一水平Address所有Person领域基本持平JSON。即使是不完全如此,这可能帮助你。 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;
    }

}

当然这不是唯一的方法,可能不会有最佳的性能,但它只是你如何在自定义解串器做反序列化。如果您PersonAddress对象就吃像10场的每使用这不应该是一个问题。

更新

我认为,你的情况 - 根据您的示例数据 - Michał Ziober's answer可能是最好的,但如果你需要更多复杂的操作比普通展开你的数据,你只需要反序列化Person类不知何故像我介绍。

© www.soinside.com 2019 - 2024. All rights reserved.