【问题标题】:Deserializing Guava's Table with Jackson throws "JsonMappingException: No suitable constructor found for type"使用 Jackson 反序列化 Guava 的表会抛出“JsonMappingException:找不到适合类型的构造函数”
【发布时间】:2016-07-02 11:21:44
【问题描述】:

我正在使用jackson-datatype-guava。我正在尝试从 JSON 反序列化一个表,但我遇到了一个异常。

我的代码是:

@Test
public void jsonTable() throws IOException {
    Table<String, String, String> table = HashBasedTable.create();
    table.put("row1", "col1", "cell11");
    table.put("row1", "col2", "cell12");
    table.put("row2", "col1", "cell21");
    table.put("row2", "col2", "cell22");

    ObjectMapper mapper = new ObjectMapper()
            .registerModule(new GuavaModule());

    String tableJson = mapper.writeValueAsString(table);
    System.out.println(tableJson);

    Table<String, String, String> deserializedTable = mapper.readValue(tableJson, HashBasedTable.class);
}

最后一行抛出的异常是:

com.fasterxml.jackson.databind.JsonMappingException: No suitable constructor found for type [simple type, class com.google.common.collect.HashBasedTable]: can not instantiate from JSON object (missing default constructor or creator, or perhaps need to add/enable type information?)
 at [Source: {"row1":{"col2":"cell12","col1":"cell11"},"row2":{"col2":"cell22","col1":"cell21"}}; line: 1, column: 2]
    at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:255)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1130)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:298)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:133)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3807)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2797)
    at com.gk.dfm.repository.impl.JsonTableTest.jsonTable(JsonTableTest.java:31)

这是有道理的,因为 HashBasedTable 没有默认构造函数。我们应该使用HashBasedTable.create() 构建它。不过我怎么能告诉杰克逊呢?

this page我找到了如何反序列化 Guava 的 Multimap:

@Test
public void convert() throws JsonParseException, JsonMappingException,
        JsonProcessingException, IOException {

    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.registerModule(new GuavaModule());

    Multimap<String, NavItem> navs = objectMapper.readValue(
            objectMapper.treeAsTokens(objectMapper.readTree(jsonString)),
            objectMapper.getTypeFactory().constructMapLikeType(
                    Multimap.class, String.class, NavItem.class));

    logger.info(navs);

    assertThat(navs.keys(), hasItems("123455", "999999"));
}

如何将其应用于表格?没有constructTableLikeType这样的东西。

【问题讨论】:

    标签: java json jackson guava


    【解决方案1】:

    首先,尝试使用jackson-datatypes-collections 而不是jackson-datatype-guava,因为it has been moved under jackson-datatype-collections to simplify management, release process.

    对 Guava 的Table 的支持似乎不完整,因为有an open issue for adding (de)serializer for it。因为它是开源的,你可以自己做(如果你这样做,请回馈!) - 你可以使用其他人写的东西,比如this pull request in old repository(还有see test for Table,表示支持序列化,但不反序列化) .

    【讨论】:

    • 谢谢。我想我只需将Table&lt;R,C,V&gt; 转换为Map&lt;R,Map&lt;C,V&gt;&gt;,然后对其进行序列化/反序列化。顺便说一句,jackson-datatypes-collections 文档应该提及库中每个集合的支持状态(特别是如果它只完成了一半 - 这是非常具有误导性的)。
    猜你喜欢
    • 1970-01-01
    • 2012-06-24
    • 2012-01-12
    • 2016-03-24
    • 2012-01-12
    • 1970-01-01
    • 2012-10-06
    相关资源
    最近更新 更多