使用 Jackson 序列化 ImmutableMap 时如何保留类型信息?
How can I preserve type info when serializing ImmutableMap using Jackson?
当我序列化HashMap
时,我可以保留类型信息以便我可以将其反序列化为相应的类型,但是这在序列化com.google.common.collect.ImmutableMap
时不起作用。如何保留类型信息?
public class ImmutableMapJacksonTest {
public static void main(String[] args) throws IOException {
ObjectMapper objectMapper = new ObjectMapper()
.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
Map<String, String> map = new HashMap<>();
map.put("k1", "v1");
map.put("k2", "v2");
// ["java.util.HashMap",{"k1":"v1","k2":"v2"}]
// preserve type info
System.out.println(objectMapper.writeValueAsString(map));
ImmutableMap<String, String> immutableMap = ImmutableMap.of("k1", "v1", "k2", "v2");
// {"k1":"v1","k2":"v2"}
// miss type info
System.out.println(objectMapper.writeValueAsString(immutableMap));
}
}
在pom.xml
中添加如下依赖。
<properties>
<jackson.version>2.11.1</jackson.version>
</properties>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-guava</artifactId>
<version>${jackson.version}</version>
</dependency>
</dependencies>
然后像下面这样创建ObjectMapper
实例,你会得到你想要的。
// https://github.com/FasterXML/jackson-docs/wiki/JacksonPolymorphicDeserialization
PolymorphicTypeValidator ptv = BasicPolymorphicTypeValidator.builder()
.allowIfSubType(Object.class)
.build();
ObjectMapper objectMapper = JsonMapper.builder()
.addModule(new GuavaModule()) // https://github.com/FasterXML/jackson-datatypes-collections
.activateDefaultTyping(ptv, ObjectMapper.DefaultTyping.EVERYTHING)
.build();
Map<String, String> map = new HashMap<>();
map.put("k1", "v1");
map.put("k2", "v2");
// ["java.util.HashMap",{"k1":"v1","k2":"v2"}]
System.out.println(objectMapper.writeValueAsString(map));
ImmutableMap<String, String> immutableMap = ImmutableMap.of("k1", "v1", "k2", "v2");
// ["com.google.common.collect.RegularImmutableMap",{"k1":"v1","k2":"v2"}]
System.out.println(objectMapper.writeValueAsString(immutableMap));
当我序列化HashMap
时,我可以保留类型信息以便我可以将其反序列化为相应的类型,但是这在序列化com.google.common.collect.ImmutableMap
时不起作用。如何保留类型信息?
public class ImmutableMapJacksonTest {
public static void main(String[] args) throws IOException {
ObjectMapper objectMapper = new ObjectMapper()
.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
Map<String, String> map = new HashMap<>();
map.put("k1", "v1");
map.put("k2", "v2");
// ["java.util.HashMap",{"k1":"v1","k2":"v2"}]
// preserve type info
System.out.println(objectMapper.writeValueAsString(map));
ImmutableMap<String, String> immutableMap = ImmutableMap.of("k1", "v1", "k2", "v2");
// {"k1":"v1","k2":"v2"}
// miss type info
System.out.println(objectMapper.writeValueAsString(immutableMap));
}
}
在pom.xml
中添加如下依赖。
<properties>
<jackson.version>2.11.1</jackson.version>
</properties>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-guava</artifactId>
<version>${jackson.version}</version>
</dependency>
</dependencies>
然后像下面这样创建ObjectMapper
实例,你会得到你想要的。
// https://github.com/FasterXML/jackson-docs/wiki/JacksonPolymorphicDeserialization
PolymorphicTypeValidator ptv = BasicPolymorphicTypeValidator.builder()
.allowIfSubType(Object.class)
.build();
ObjectMapper objectMapper = JsonMapper.builder()
.addModule(new GuavaModule()) // https://github.com/FasterXML/jackson-datatypes-collections
.activateDefaultTyping(ptv, ObjectMapper.DefaultTyping.EVERYTHING)
.build();
Map<String, String> map = new HashMap<>();
map.put("k1", "v1");
map.put("k2", "v2");
// ["java.util.HashMap",{"k1":"v1","k2":"v2"}]
System.out.println(objectMapper.writeValueAsString(map));
ImmutableMap<String, String> immutableMap = ImmutableMap.of("k1", "v1", "k2", "v2");
// ["com.google.common.collect.RegularImmutableMap",{"k1":"v1","k2":"v2"}]
System.out.println(objectMapper.writeValueAsString(immutableMap));