这是对 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,但没有结果。
您可以尝试这个解决方案,效果很好: 您必须从 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
让我知道