我遇到的问题是我有一个在很多地方使用的公共对象,在这个例子中,常见的对象是Student。 Student是另一个名为Enrollment的对象的属性(但它可能是许多其他类的属性)。现在没有自定义序列化应用于学生我会得到这样的东西:
{"会话":"周三上午9点""学生":{" firstName":" Joe" " lastName的":"布罗格斯"}}
我想要做的是将自定义序列化程序应用于Student,以便它出现在我的代码中的任何位置,例如在Enrollment类中,我会得到这个:
{"会话":"周三上午9点"" firstName":" Joe"," lastName": "布罗格斯"}
或者如果我这样选择:
{"会话":"周三上午9点""第一":" Joe","最后": "布罗格斯"}
或者甚至可以这样:
{"会话":"周三上午9点""名称":" Joe Bloggs"}
这是我的示例代码:
public class Enrolment {
private String session;
private Student student;
public Enrolment(String session, Student student) {
this.session = session;
this.student = student;
}
public String getSession() {
return session;
}
public void setSession(String session) {
this.session = session;
}
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
}
@JsonSerialize(using = StudentSerializer.class)
public class Student {
private String firstName;
private String lastName;
public Student(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
public class StudentSerializer extends JsonSerializer<Student> {
@Override
public void serialize(Student value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
// ??????
}
}
public class Launcher {
public static void main(String[] args) throws Exception{
ObjectMapper mapper = new ObjectMapper();
Student student = new Student("Joe", "Bloggs");
Enrolment enrolment = new Enrolment("9am Wednesday", student);
System.out.println(mapper.writeValueAsString(enrolment));
}
}
如果你也可以提供一个反序列化器,它可以接受一个所需的json序列化示例并从中创建Student对象,这将是一个巨大的奖励。同样,反序列化器就像序列化器必须连接到Student对象一样,这样它出现的任何地方都会执行相同的操作。
谢谢:)
答案 0 :(得分:1)
您希望从版本1.9开始提供@JsonUnwrapped
注释。您可以查看版本2.0 here的文档,但基本上您可以:
public class Enrolment {
...
@JsonUnwrapped
public Student getStudent() {
return student;
}
...
}
你会得到你的第一个选择:
{"session":"9am Wednesday","firstName":"Joe","lastName":"Bloggs"}
注释依赖于默认的序列化程序。一方面,您不能拥有Student
的自定义序列化程序,但另一方面,您可以使用@JsonProperty
等其他注释并自定义Student
来获得第二个选项。
通过在Student
中添加自定义getter和setter,您的第三个选项也会做得最好。在这种情况下,您将使用@JsonIgnore
来避免序列化其他属性。
答案 1 :(得分:0)
这是我偶然发现的另一个选择:
public class Enrolment {
private String session;
private Student student;
public Enrolment(String session, Student student) {
this.session = session;
this.student = student;
}
public String getSession() {
return session;
}
public void setSession(String session) {
this.session = session;
}
@JsonUnwrapped
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
}
public class StudentUnwrappingBeanSerializer extends UnwrappingBeanSerializer {
public StudentUnwrappingBeanSerializer(BeanSerializerBase src, NameTransformer transformer) {
super(src, transformer);
}
@Override
public JsonSerializer<Object> unwrappingSerializer(NameTransformer transformer) {
return new StudentUnwrappingBeanSerializer(this, transformer);
}
@Override
protected void serializeFields(Object bean, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException {
Student student = (Student) bean;
jgen.writeStringField("first", student.getFirstName());
jgen.writeStringField("last", student.getLastName());
}
@Override
public boolean isUnwrappingSerializer() {
return true;
}
}
public class Launcher {
public static void main(String[] args) throws Exception{
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new Module() {
@Override
public String getModuleName() {
return "my.module";
}
@Override
public Version version() {
return Version.unknownVersion();
}
@Override
public void setupModule(SetupContext context) {
context.addBeanSerializerModifier(new BeanSerializerModifier() {
@Override
public JsonSerializer<?> modifySerializer(SerializationConfig config, BeanDescription beanDesc, JsonSerializer<?> serializer) {
if(beanDesc.getBeanClass().equals(Student.class)) {
return new StudentUnwrappingBeanSerializer((BeanSerializerBase) serializer, NameTransformer.NOP);
}
return serializer;
}
});
}
});
Student student = new Student("Joe", "Bloggs");
ExtendableOption<StudyType> studyType = new ExtendableOption<>(StudyType.DISTANCE);
Enrolment enrolment = new Enrolment("9am Wednesday", student, studyType);
System.out.println(mapper.writeValueAsString(enrolment));
}
}