为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

万千封印 2022-05-21 20:50:06
我正在尝试将某些 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 手动映射每个字段来解决这个问题,但是在我的实际项目中,这不是一个好的解决方案。使用杰克逊是否有解决此类问题的方法?另外,如果之前有人问过这个问题,那么代表我道歉,因为我已经深入寻找解决方案并且可能还没有看到它。.
查看完整描述

3 回答

?
慕尼黑5688855

TA贡献1848条经验 获得超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'}}


查看完整回答
反对 回复 2022-05-21
?
缥缈止盈

TA贡献2041条经验 获得超4个赞

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



查看完整回答
反对 回复 2022-05-21
?
慕斯709654

TA贡献1840条经验 获得超5个赞

我理解你的问题,所以它是关于平面 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 的答案可能是最好的,但如果您需要比简单展开数据更复杂的处理,您只需要Person像我介绍的那样以某种方式反序列化类。


查看完整回答
反对 回复 2022-05-21
  • 3 回答
  • 0 关注
  • 101 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信