我有几个POJO,它们都有相同的抽象基类。我想序列化和反序列化,而不需要类型检查或转换。
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.WRAPPER_OBJECT,
property = "type"
)
@JsonSubTypes({
@JsonSubTypes.Type(value = UserEvent.class, name = "user"),
@JsonSubTypes.Type(value = SystemEvent.class, name = "system")
})
public abstract class Event {
private Long id;
private Date date;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
}
@JsonTypeName("user")
public class UserEvent extends Event {
private String userId;
private String userName;
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
@JsonTypeName("system")
public class SystemEvent extends Event {
private String source;
public String getSource() {
return source;
}
public void setSource(String source) {
this.source = source;
}
}当我将UserEvent序列化为JSON时,我得到了下面的输出,输出的类型名称是包装器对象。
{
"user" : {
"id" : 42,
"date" : 1568214606656,
"userId" : "123123",
"userName" : "Bob"
}
}到目前一切尚好。如果我试图反序列化同一个JSON对象,它将失败。
@Test
void deserializeUserEvent() throws Exception {
String json =
"\"user\" : {\n" +
" \"id\" : 42,\n" +
" \"date\" : 1568211488351,\n" +
" \"userId\" : \"123123\",\n" +
" \"userName\" : \"Bob\"\n" +
" }";
ObjectMapper mapper = new ObjectMapper();
Event event = mapper
.readerFor(Event.class)
.readValue(json); // ERROR
assertSame(UserEvent.class, event.getClass());
}是否可以仅通过声明抽象类型来反序列化具体类型?
发布于 2019-09-11 16:07:43
是的你可以用它。我在这里使用对象映射器将对象写成字符串。
UserEvent ue = new UserEvent();
ue.setUserName("Some Username");
ue.setUserId("userID");
ue.setDate(new Date());
ue.setId(123123L);
ObjectMapper objectMapper = new ObjectMapper();
String userEventString = objectMapper.writeValueAsString(ue);{“用户”:{“id”:123123,“日期”:1568217548148,"userId":"userID","userName":"asdlasd"}}
并将其解读为:
Event event = objectMapper.readValue(userEventString, Event.class);此外,ObjectMapper还为您提供了使用以下内容的可能性:
ObjectMapper mapperWithMixin = new ObjectMapper()
.addMixIn(Event.class, UserEvent.class);其中,Event.class是您的目标类,UserEvent.class是您提供的json对象。
发布于 2019-09-11 15:53:42
是的,仅通过声明抽象类型就可以反序列化具体类型。
要反序列化的字符串应该是正确的JSON。
String json = "{\"user\":{\"id\":42,\"date\":1568216805617,\"userId\":\"123123\",\"userName\":\"Bob\"}}";
Event event = mapper.readValue(json, Event.class);以上代码适用于jackson的最新版本-databind- 2.9.9.3
https://stackoverflow.com/questions/57892310
复制相似问题