2016-09-29 59 views
0

挣扎着看起来像平凡的东西,应该没有任何问题的工作。我有带“@class”属性的JSON,并且在调用时不知道它是类readValue()想将其反序列化到由“@class”引用的类的对象中。我取而代之的是“LinkedHashMap”。平凡的JSON杰克逊多态反序列化

@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

+0

不知道我理解你的问题,但反序列化的正确用法就是'Sample obj = mapper.readValue(json,Sample.class);',不投射。 – Mena

+0

@Mena事实上,情况当然更复杂一些,这只是举例说明所需的行为。我不能使用类型信息。 – Stas

回答

1

杰克逊将其转换为LinkedhashMap,这样以后,我们就可以使用到转换给LinkedhashMap其转换方法引入自定义对象。所以在这里你需要再增加一个步骤。

E.g:

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类。

+0

Thx,这是可行的。我可以从地图读取“@class”属性,获取该类并将其传递到convertValue()。我只是希望把所有的管道都放在杰克逊手柄上。 – Stas

0

显然,加入这一行使得这个测试工作:

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

在试样类注释的情况下是没有必要的。