【问题标题】:Trivial JSON jackson polymorphic deserialization简单的 JSON 杰克逊多态反序列化
【发布时间】:2016-09-29 10:43:38
【问题描述】:

在一些看起来微不足道的事情上挣扎,应该可以毫无问题地工作。我有带有“@class”属性的 JSON,并且在调用时不知道它的类 readValue() 想要将其反序列化为“@class”引用的类的对象。我得到的是“LinkedHashMap”。

@Test
public void toJsonAndBack() throws Exception {
    ObjectMapper mapper = new ObjectMapper();
    String json = mapper.writeValueAsString(new Sample("id"));
    assertTrue(json.contains("@class"));
    Sample obj = (Sample)mapper.readValue(json, Object.class);
}

@JsonTypeInfo(use=JsonTypeInfo.Id.CLASS)
static class Sample {
    private String id;

    public Sample() {
    }

    public Sample(String id) {
        this.id = id;
    }

    public String getId() {
        return id;
    }
}

对不起,如果重复,但找​​不到完全相同的问题。大多数人都有更复杂的情况,其中有基类,也有注释等。这些情况实际上工作得很好。

我正在使用杰克逊 2.6.6

【问题讨论】:

  • 不确定我是否理解您的问题,但反序列化的正确习惯用法就是 Sample obj = mapper.readValue(json, Sample.class);,不进行强制转换。
  • @Mena 实际上,当然,案例要复杂一些,这只是说明所需行为的示例。我不能使用类型信息。

标签: java json serialization jackson deserialization


【解决方案1】:

Jackson 将其转换为LinkedhashMap,以便稍后我们可以使用它的 convert 方法将给定的LinkedhashMap 转换为自定义对象。所以这里需要多加一步。

例如:

ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(new Sample("id"));
Object obj = mapper.readValue(json, Object.class);
Sample sample = mapper.convertValue(obj, Sample.class);

因此,您可以将这个 obj 保存在某个地方,并在方便时将其转换为 Sample 类。

【讨论】:

  • 谢谢,这是可行的。我可以从地图中读取“@class”属性,获取类并将其传递给 convertValue()。我只是希望将所有管道留给杰克逊处理。
【解决方案2】:

显然添加这一行使这个测试工作:

mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);

在这种情况下,不需要对 Sample 类进行注释。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-04-07
    • 2015-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-13
    相关资源
    最近更新 更多