我有class Admin extends User {}
。 Admin
和User
都延伸@XmlRootElement
@XmlRootElement
public class User {
....
}
@XmlRootElement
public class Admin extends User {
String statement;
}
我将这个Json发送到正确的JaxRS服务:
{
"id": "84",
"content": "blablah",
"user": {
"id": 1,
"email": "nicolas@robusta.io",
"name": "Nicolas",
"male": true,
"admin": true,
"statement":"hello world"
}
}
这是Web服务。该评论应该有User
,但我们这里有一个管理员,statement
字段不为User
。
@POST
@Path("{id}/comments")
public Response createComment(@PathParam("id") long topicId, Comment comment) { ... }
杰克逊不接受Comment
作为Comment
,因为其User
是Admin
:
@XmlRootElement
public class Comment {
String id;
String content;
User user = null;
}
我应该如何告诉杰克逊接受任何类型的用户?如何做到最兼容Java EE(即使用具有另一个Json处理程序的服务器)?
答案 0 :(得分:1)
使用多态对象的jackson方法是在json中添加一些额外的字段并使用(function() {
var obj = {
fn: function(a) {
var f = v=> {
debugger;
console.log("Arguments length " + arguments.length);
};
return f(a, 6, 7, 8);
}
};
obj.fn(1);
}
)();
如果你可以将你的json更改为
@JsonTypeInfo
然后你可以简单地使用
"user": {
"type": "Admin",
...
}
如果你不能改变你的json,那么事情会变得复杂,因为没有默认的方法来处理这种情况,你必须编写自定义反序列化器。基本的简单案例看起来像这样:
@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;
}
您可以在ObjectMapper上注册
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 mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(User.class, new PolymorphicDeserializer());
mapper.registerModule(module);