首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >沙漠化多态JSON字符串

沙漠化多态JSON字符串
EN

Stack Overflow用户
提问于 2019-09-11 15:22:40
回答 2查看 68关注 0票数 1

我有几个POJO,它们都有相同的抽象基类。我想序列化和反序列化,而不需要类型检查或转换。

代码语言:javascript
复制
@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时,我得到了下面的输出,输出的类型名称是包装器对象。

代码语言:javascript
复制
{
  "user" : {
    "id" : 42,
    "date" : 1568214606656,
    "userId" : "123123",
    "userName" : "Bob"
  }
}

到目前一切尚好。如果我试图反序列化同一个JSON对象,它将失败。

代码语言:javascript
复制
@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());
}

是否可以仅通过声明抽象类型来反序列化具体类型?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-09-11 16:07:43

是的你可以用它。我在这里使用对象映射器将对象写成字符串。

代码语言:javascript
复制
    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"}}

并将其解读为:

代码语言:javascript
复制
Event event = objectMapper.readValue(userEventString, Event.class);

此外,ObjectMapper还为您提供了使用以下内容的可能性:

代码语言:javascript
复制
ObjectMapper mapperWithMixin = new ObjectMapper()
        .addMixIn(Event.class, UserEvent.class);

其中,Event.class是您的目标类,UserEvent.class是您提供的json对象。

票数 3
EN

Stack Overflow用户

发布于 2019-09-11 15:53:42

是的,仅通过声明抽象类型就可以反序列化具体类型。

要反序列化的字符串应该是正确的JSON。

代码语言:javascript
复制
String json = "{\"user\":{\"id\":42,\"date\":1568216805617,\"userId\":\"123123\",\"userName\":\"Bob\"}}";
Event event = mapper.readValue(json, Event.class);

以上代码适用于jackson的最新版本-databind- 2.9.9.3

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57892310

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档