无法从字符串构造 java.lang.Class 类型的映射键:无法将键解析为 Class
Can not construct Map key of type java.lang.Class from String: unable to parse key as Class
我在反序列化包含以 Class
作为键的地图的对象时遇到问题:
public class TestSerializeMap {
public static class TestClass {
private Map<Class<? extends Object>, String> map = new HashMap<>();
public TestClass() {
}
public Map<Class<? extends Object>, String> getMap() {
return map;
}
}
@Test
public void testPropertyMapWithClassAsKey() throws Exception {
TestClass testClass = new TestClass();
testClass.getMap().put(ArrayList.class, "ArrayList");
testClass.getMap().put(HashMap.class, "HashMap");
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(testClass);
System.out.println(json);
mapper.readValue(json, TestClass.class);
}
}
引发此异常:
com.fasterxml.jackson.databind.exc.InvalidFormatException: Can not construct Map key of type java.lang.Class from String "class java.util.ArrayList": not a valid representation: Can not construct Map key of type java.lang.Class from String "class java.util.ArrayList": unable to parse key as Class
at [Source: {
"map" : {
"class java.util.ArrayList" : "ArrayList",
"class java.util.HashMap" : "HashMap"
}
}; line: 3, column: 5]
at [Source: {
"map" : {
"class java.util.ArrayList" : "ArrayList",
"class java.util.HashMap" : "HashMap"
}
}; line: 3, column: 5] (through reference chain: org.test.TestClass["map"])
at com.fasterxml.jackson.databind.exc.InvalidFormatException.from(InvalidFormatException.java:55)
at com.fasterxml.jackson.databind.DeserializationContext.weirdKeyException(DeserializationContext.java:913)
at com.fasterxml.jackson.databind.deser.std.StdKeyDeserializer.deserializeKey(StdKeyDeserializer.java:131)
at com.fasterxml.jackson.databind.deser.std.MapDeserializer._readAndBind(MapDeserializer.java:404)
at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:333)
at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:25)
...
当我尝试直接序列化地图时:
@Test
public void testMapWithClassAsKey() throws Exception {
Map<Class<? extends Object>, String> map = new HashMap<>();
map.put(ArrayList.class, "ArrayList");
map.put(HashMap.class, "HashMap");
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(map);
System.out.println(json);
mapper.readValue(json, Map.class);
}
然后它就可以正常工作了。
我在第一次测试中错过了什么?
编辑:
发现第二次测错了。应该是:
@Test
public void testMapWithClassAsKey() throws Exception {
Map<Class<? extends Object>, String> map = new HashMap<>();
map.put(ArrayList.class, "ArrayList");
map.put(HashMap.class, "HashMap");
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(map);
System.out.println(json);
mapper.readValue(json, new TypeReference<Map<Class<? extends Object>, String>>(){});
}
现在它失败了,与第一个异常相同。
我在 github 上提交了调查结果。 FasterXML 的 Tatu 调查了它并解决了这个问题。问题是地图中 Class<?>
个键的序列化。
应该在 jackson-databind 2.5.1 版本中修复
我在反序列化包含以 Class
作为键的地图的对象时遇到问题:
public class TestSerializeMap {
public static class TestClass {
private Map<Class<? extends Object>, String> map = new HashMap<>();
public TestClass() {
}
public Map<Class<? extends Object>, String> getMap() {
return map;
}
}
@Test
public void testPropertyMapWithClassAsKey() throws Exception {
TestClass testClass = new TestClass();
testClass.getMap().put(ArrayList.class, "ArrayList");
testClass.getMap().put(HashMap.class, "HashMap");
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(testClass);
System.out.println(json);
mapper.readValue(json, TestClass.class);
}
}
引发此异常:
com.fasterxml.jackson.databind.exc.InvalidFormatException: Can not construct Map key of type java.lang.Class from String "class java.util.ArrayList": not a valid representation: Can not construct Map key of type java.lang.Class from String "class java.util.ArrayList": unable to parse key as Class
at [Source: {
"map" : {
"class java.util.ArrayList" : "ArrayList",
"class java.util.HashMap" : "HashMap"
}
}; line: 3, column: 5]
at [Source: {
"map" : {
"class java.util.ArrayList" : "ArrayList",
"class java.util.HashMap" : "HashMap"
}
}; line: 3, column: 5] (through reference chain: org.test.TestClass["map"])
at com.fasterxml.jackson.databind.exc.InvalidFormatException.from(InvalidFormatException.java:55)
at com.fasterxml.jackson.databind.DeserializationContext.weirdKeyException(DeserializationContext.java:913)
at com.fasterxml.jackson.databind.deser.std.StdKeyDeserializer.deserializeKey(StdKeyDeserializer.java:131)
at com.fasterxml.jackson.databind.deser.std.MapDeserializer._readAndBind(MapDeserializer.java:404)
at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:333)
at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:25)
...
当我尝试直接序列化地图时:
@Test
public void testMapWithClassAsKey() throws Exception {
Map<Class<? extends Object>, String> map = new HashMap<>();
map.put(ArrayList.class, "ArrayList");
map.put(HashMap.class, "HashMap");
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(map);
System.out.println(json);
mapper.readValue(json, Map.class);
}
然后它就可以正常工作了。 我在第一次测试中错过了什么?
编辑:
发现第二次测错了。应该是:
@Test
public void testMapWithClassAsKey() throws Exception {
Map<Class<? extends Object>, String> map = new HashMap<>();
map.put(ArrayList.class, "ArrayList");
map.put(HashMap.class, "HashMap");
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(map);
System.out.println(json);
mapper.readValue(json, new TypeReference<Map<Class<? extends Object>, String>>(){});
}
现在它失败了,与第一个异常相同。
我在 github 上提交了调查结果。 FasterXML 的 Tatu 调查了它并解决了这个问题。问题是地图中 Class<?>
个键的序列化。
应该在 jackson-databind 2.5.1 版本中修复