使用 Jackson 反序列化使用自定义 getter 创建的 JSON 和解包对象

问题描述 投票:0回答:1

这是对 Jackson custom getters 的回答的后续问题。

该解决方案有效并创建了正确的 JSON。问题是反序列化。我有一个未包装的对象,其中一些属性未在 JSON 中显示,而是被新属性替换(例如名字+姓氏 => 名称)。

这已正确序列化为

{"age":22,"name":"Alex Doe"}

这个类不能编辑,所以我们依赖mixin。

反序列化的问题是,

PersonSerializer.setFullname()
PersonSerializer.setPerson()
之前被调用,可能是因为属性在子对象之前被反序列化。这迫使我在
Person
创建
PersonSerializer
时创建一个
ObjectMapper
对象。当使用仅包含年龄的
Person
对象反序列化年龄时,此
Person
对象将被覆盖:

firstName: null, surname: null, age: 22

我可以将

fullname
存储在
setFullname()
中,并在调用
person
时将其填充到
setPerson()
中,但这感觉不正确。

解决这个问题的正确方法是什么?

代码:

public final class Person {

    private String firstName;
    private String surname;
    private int age;

    public Person() {
        super();
    }

    Person(final String firstName, final String surname, final int age) {
        super();
        this.firstName = firstName;
        this.surname = surname;
        this.age = age;
    }
 //getter and setter
}

基于答案的序列化助手和混合:

public class PersonSerializer {

    private Person person;

    public PersonSerializer() {
        super();
        person = new Person(); //needed, otherwise NPE in setFullname()
    }

    @JsonUnwrapped
    Person getPerson() {
        return person;
    }

    //customer getter to join firstname and surname
    @JsonGetter("name")
    String fullName() {
        return person.getFirstName() + " " + person.getSurname();
    }

    @JsonSetter("name")
    public void setFullname(final String fullName) {
        final String[] s = fullName.split(" ");
        person.setFirstName(s[0]);
        person.setSurname(s[1]);
    }

    public void setPerson(Person p) {
        person = p;
    }
}

abstract class PersonMixin {

    @JsonIgnore String firstName;
    @JsonIgnore String surname;
}

测试代码:

public static void main(String[] args)

        throws JsonProcessingException {

        final ObjectMapper mapper = new ObjectMapper().addMixIn(Person.class, PersonMixin.class);
        mapper.setVisibility(PropertyAccessor.GETTER, JsonAutoDetect.Visibility.ANY);
        final PersonSerializer alex = new PersonSerializer();
        alex.setPerson(new Person("Alex", "Doe", 22));
        final String s = mapper.writeValueAsString(alex);
        out.println(s);

        final Person newAlex = mapper.readValue(s, PersonSerializer.class).getPerson();
        out.println(String.format(
            "firstName: %s, surname: %s, age: %d",
            newAlex.getFirstName(),
            newAlex.getSurname(),
            newAlex.getAge()
        ));
    }

我搜索了示例、文档和 StackOverflow,但没有结果。

java json jackson deserialization json-deserialization
1个回答
0
投票

您可以尝试这个解决方案,效果很好: 您必须从 get 方法中获取此注释

@JsonUnwrapped

public class PersonSerializer {

    private Person person;

    public PersonSerializer() {
        super();
    }

    public Person getPerson() {
        return person;
    }

    public void setPerson(Person p) {
        person = p;
    }

    //customer getter to join firstname and surname
    @JsonGetter("name")
    public String fullName() {
        return person.getFirstName() + " " + person.getSurname();
    }

    @JsonSetter("name")
    public void setFullName(final String fullName) {
        final String[] s = fullName.split(" ");
        person.setFirstName(s[0]);
        person.setSurname(s[1]);
    }




    public static void main(String[] args) throws JsonProcessingException {

        final ObjectMapper mapper = new ObjectMapper();
        final PersonSerializer alex = new PersonSerializer();
        alex.setPerson(new Person("Alex", "Doe", 22));
        final String s = mapper.writeValueAsString(alex);
        System.out.println(s);

        final Person newAlex = mapper.readValue(s, PersonSerializer.class).getPerson();
        System.out.println(String.format(
                "firstName: %s, surname: %s, age: %d",
                newAlex.getFirstName(),
                newAlex.getSurname(),
                newAlex.getAge()
        ));
    }
}

输出是:

{"person":{"firstName":"Alex","surname":"Doe","age":22},"name":"Alex Doe"}
firstName: Alex, surname: Doe, age: 22

让我知道

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