且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

与JaxRS和Jackson的多态性

更新时间:2023-01-17 11:03:56

具有多态性的jackson方法对象是在你的json中添加一些额外的字段并使用 @JsonTypeInfo 如果你可以将你的json更改为类似

The jackson approach with polymorphic objects is to add some additional field in your json and use @JsonTypeInfo If you can change your json to something like

"user": {
     "type": "Admin",
     ...
 }

然后你可以简单地使用

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
@JsonSubTypes({
        @JsonSubTypes.Type(name = "User", value = User.class),
        @JsonSubTypes.Type(name = "Admin", value = Admin.class)
})
static class User {
    public String id;
}






如果你不能改变你的json,然后事情会变得复杂,因为没有默认的方法来处理这种情况,你将不得不编写自定义反序列化器。基本简单的情况看起来像这样:


If you can't change your json, then things can get complicated, because there is no default way to handle such a case and you will have to write custom deserializer. And base simple case would look something like this:

public static class PolymorphicDeserializer extends JsonDeserializer<User> {
    ObjectMapper mapper = new ObjectMapper();

    @Override
    public User deserialize(JsonParser p, DeserializationContext ctxt)
            throws IOException, JsonProcessingException {
        JsonNode tree = p.readValueAsTree();

        if (tree.has("statement")) // <= hardcoded field name that Admin has
            return mapper.convertValue(tree, Admin.class);

        return mapper.convertValue(tree, User.class);

    }
}

您可以在ObjectMapper上注册

You can register it on ObjectMapper

ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(User.class, new PolymorphicDeserializer());
mapper.registerModule(module);

或带注释:

@JsonDeserialize(using = PolymorphicDeserializer.class)
class User {
    public String id;
}