Java 与JaxRS和Jackson的多态性
我有Java 与JaxRS和Jackson的多态性,java,jakarta-ee,jackson,jax-rs,Java,Jakarta Ee,Jackson,Jax Rs,我有类管理员扩展用户{}Admin和User都扩展了@XmlRootElement @XmlRootElement public class User { .... } @XmlRootElement public class Admin extends User { String statement; } 我将此Json发送到正确的JaxRS服务: { "id": "84", "content": "blablah", "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服务。注释应该有一个用户
,但我们这里有一个管理员,他有一个语句
字段,而用户
不知道该字段
@POST
@Path("{id}/comments")
public Response createComment(@PathParam("id") long topicId, Comment comment) { ... }
杰克逊不接受评论
作为评论
,因为其用户
是管理员
:
@XmlRootElement
public class Comment {
String id;
String content;
User user = null;
}
我应该如何告诉Jackson接受任何类型的用户?如何做到这一点最与Java EE兼容(即与具有另一个Json处理程序的服务器兼容)?使用多态对象的jackson方法是在Json中添加一些附加字段,如果可以将Json更改为
"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,那么事情可能会变得复杂,因为没有默认的方法来处理这种情况,您必须编写自定义反序列化程序。基本的简单情况如下所示:
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);
}
}
或带有注释:
@JsonDeserialize(using = PolymorphicDeserializer.class)
class User {
public String id;
}
使用多态对象的jackson方法是在json中添加一些附加字段,如果可以将json更改为
"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,那么事情可能会变得复杂,因为没有默认的方法来处理这种情况,您必须编写自定义反序列化程序。基本的简单情况如下所示:
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);
}
}
或带有注释:
@JsonDeserialize(using = PolymorphicDeserializer.class)
class User {
public String id;
}
您是否在注释Classic中尝试了@XmlElement(name=“user”,type=Admin.class)它并不总是管理员。用户或管理员可以创建注释。您是否在注释类中尝试了@xmlement(name=“User”,type=Admin.class)它并不总是管理员。用户或管理员可以创建注释