使用 Jackson throws "JsonMappingException: No suitable constructor found for type" 反序列化 Guava 的 Table
Deserializing Guava's Table with Jackson throws "JsonMappingException: No suitable constructor found for type"
我正在使用 jackson-datatype-guava
。我正在尝试从 JSON 反序列化 Table,但出现异常。
我的代码是:
@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"));
}
如何将它应用到 Table?没有constructTableLikeType.
这样的东西
首先,尝试使用 jackson-datatypes-collections 而不是 jackson-datatype-guava,因为 它 已移至 jackson-datatype-collections 下以简化管理、发布过程。
Guava 的 Table
支持似乎不完整,因为有 an open issue for adding (de)serializer for it. Since it's open source, you can do it yourself (please contribute back if you do so!) - you can use what other other people wrote, like this pull request in old repository (also see test for Table
表示支持序列化,但不支持反序列化。
我正在使用 jackson-datatype-guava
。我正在尝试从 JSON 反序列化 Table,但出现异常。
我的代码是:
@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"));
}
如何将它应用到 Table?没有constructTableLikeType.
这样的东西首先,尝试使用 jackson-datatypes-collections 而不是 jackson-datatype-guava,因为 它 已移至 jackson-datatype-collections 下以简化管理、发布过程。
Guava 的 Table
支持似乎不完整,因为有 an open issue for adding (de)serializer for it. Since it's open source, you can do it yourself (please contribute back if you do so!) - you can use what other other people wrote, like this pull request in old repository (also see test for Table
表示支持序列化,但不支持反序列化。