我尝试使用Jackson
将JSON数组反序列化为Java对象,后者持久保存到我的MongoDB中。我发现许多教程通过添加来处理这种多态性:
@JsonTypeInfo(use=Id.CLASS,property="_class")
到Super-class
。但是,就我而言,我无法修改Super-class
。那么,有没有一些解决方案来解决它而不修改Super-class
?这是我的代码:
public class User {
@JsonProperty("_id")
private String id;
private List<Identity> identities; // <-- My List contains objects of an abstract class; Identity
public User(){
identities = new ArrayList<Identity>();
}
public static Iterable<User> findAllUsers(){
return users().find().as(User.class); // Always give me the errors
}
/*More code*/
}
它总是给我错误 - Can not construct instance of securesocial.core.Identity, problem: abstract types either need to be mapped to concrete types, have custom deserializer, or be instantiated with additional type information
。
答案 0 :(得分:0)
您可以使用@JsonDeserilize annotation将具体实现类绑定到抽象类。如果您无法修改抽象类,可以使用the Jackson Mix-in annotations告诉Jackson如何找到实现类。
以下是一个例子:
public class JacksonAbstract {
public static class User {
private final String id;
private final List<Identity> identities;
@JsonCreator
public User(@JsonProperty("_id") String id, @JsonProperty("identities") List<Identity> identities) {
this.id = id;
this.identities = identities;
}
@JsonProperty("_id")
public String getId() {
return id;
}
public List<Identity> getIdentities() {
return identities;
}
}
public static abstract class Identity {
public abstract String getField();
}
@JsonDeserialize(as = IdentityImpl.class)
public static abstract class IdentityMixIn {
}
public static class IdentityImpl extends Identity {
private final String field;
public IdentityImpl(@JsonProperty("field") String field) {
this.field = field;
}
@Override
public String getField() {
return field;
}
}
public static void main(String[] args) throws IOException {
User u = new User("myId", Collections.<Identity>singletonList(new IdentityImpl("myField")));
ObjectMapper mapper = new ObjectMapper();
mapper.addMixInAnnotations(Identity.class, IdentityMixIn.class);
String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(u);
System.out.println(json);
System.out.println(mapper.readValue(json, User.class));
}
}