如何反序列化JSON数组包含一个抽象类而不修改父类?

时间:2014-05-09 21:27:04

标签: java json mongodb jackson jongo

我尝试使用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

1 个答案:

答案 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));
    }
}