【问题标题】:Can not construct Map key of type java.lang.Class from String: unable to parse key as Class无法从 String 构造 java.lang.Class 类型的 Map 键:无法将键解析为 Class
【发布时间】:2015-01-18 21:00:20
【问题描述】:

我在反序列化包含以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>>(){});
}

现在它失败了,异常与第一个相同。

【问题讨论】:

  • 是的,我在发布之前检查了它。我正在使用杰克逊 2.6.0。仍然不知道如何解决问题。
  • 好吧,编写你自己的 ClassDeserializer ;) 显然,在 JSON 的“org.codehaus.jackson”实现中有一个(与 fastxml 中的不同)。可以试试吗?
  • 我认为我不需要反序列化器,当 map 不是类中的属性时(第二次测试),它会正确反序列化。类解串器应该已经是 Jackson 的一部分。我认为我缺少一些配置。
  • 是的,刚刚测试,它不起作用。我现在唯一可以建议您的事情(因为我没有时间自己做)是调试工作场景 - 特别是在成功和失败的情况下都选择反序列化器的部分。它应该会给你答案,你所拥有的堆栈跟踪是一个很好的起点;)

标签: java jackson json-deserialization


【解决方案1】:

我在github 上提交了调查结果。 FasterXML 的 Tatu 对其进行了调查并修复了该问题。问题是映射中Class&lt;?&gt; 键的序列化。

它应该在jackson-databind 2.5.1版本中修复

【讨论】:

    猜你喜欢
    • 2021-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-22
    • 1970-01-01
    • 2013-11-24
    • 2013-12-14
    相关资源
    最近更新 更多