Java 在内部类没有默认构造函数时使用Jackson解组JSON

Java 在内部类没有默认构造函数时使用Jackson解组JSON,java,json,jackson,Java,Json,Jackson,我使用Jackson库封送了一个具有内部类(非静态)的类对象,该库工作得非常好。但是,我在取消封送对象时遇到问题。原因是我的内部类没有任何默认构造函数。我在这里复制了示例代码: public class JsonMarshallUnMarshall { public static void main(String[] args) { Person person = new Person(); person.setId(2222); person.setName("My Name"); Perso

我使用Jackson库封送了一个具有内部类(非静态)的类对象,该库工作得非常好。但是,我在取消封送对象时遇到问题。原因是我的内部类没有任何默认构造函数。我在这里复制了示例代码:

public class JsonMarshallUnMarshall {
public static void main(String[] args) {
Person person = new Person();
person.setId(2222);
person.setName("My Name");
Person.Student student = person.new Student(44887);
person.setStudent(student);
String personJsonValue = null;

// Marshalling
System.out.println("====Marshalling====");
ObjectMapper mapper = new ObjectMapper();
mapper.getSerializationConfig().addMixInAnnotations(Person.Student.class, MixIn.class);
mapper.getDeserializationConfig().addMixInAnnotations(Person.Student.class, MixIn.class);

try {
personJsonValue = mapper.writeValueAsString(person);
System.out.println(personJsonValue);
} catch (JsonGenerationException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

// UnMarshalling
System.out.println("====Unmarshalling====");
Person unMarshalledPerson = null;
try {
unMarshalledPerson = mapper
.readValue(personJsonValue, Person.class);
System.out.println("id: " + unMarshalledPerson.getId());
System.out.println("name: " + unMarshalledPerson.getName());
System.out.println("student id: " + unMarshalledPerson.getStudent().getStudentId());
} catch (JsonParseException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}

class Person {
private int id;
private String name;
private Student student;
public Person() {
}
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public class Student {
private int studentId;
public int getStudentId() {
return studentId;
}
public void setStudentId(int studentId) {
this.studentId = studentId;
}
public Student(int studentId) {
this.studentId = studentId;
}
}
}

abstract class MixIn {
public MixIn(@JsonProperty("studentId") int newStudentId) {
}
@JsonProperty("studentId")
abstract int getNewStudentId();
}
在执行代码时,我得到一个异常,如下所示:

org.codehaus.jackson.map.JsonMappingException: No suitable constructor found for type [simple type, class com.tnsi.cnam.batch.utilities.Person$Student]: can not instantiate from JSON object (need to add/enable type information?)
at [Source: java.io.StringReader@1abab88; line: 1, column: 41] (through reference chain: com.tnsi.cnam.batch.utilities.Person["student"])

有没有办法解决这个问题。。。我无法放置默认构造函数,因为实际类来自thirdparty jar。

当然。但你可能不会喜欢它。您需要编写自己的自定义反序列化程序。可以找到一个非常全面的例子来说明如何做到这一点。

我会使用一个自定义的
MyPerson
对象并手动映射到外部的
Person
表单。这只是一个示例代码,实际的类非常庞大,有这么多实例变量。维护另一个类将导致代码重复。如果我理解错了,请告诉我。如果这个类在他自己的jar中,他可以使用简单的
toString
fromString
方法。或者,他可以创建模型包装器类和工厂,以便在它们之间进行转换。然而,最干净的方法是@Mikkel提到的,创建自定义反序列化程序。对于你
Student
来说,这个例子无论如何都很简单。嗨,影子爬行者,你能详细说明你的解决方案吗。我有一个类似的例子,要创建的对象属于第三方,因此无法更改。我确实可以选择创建反序列化程序,但如果有更简单/通用的方法,我完全支持。