我有一个包含Map的域对象:
private Map<AutoHandlingSlotKey, LinkedHashSet<AutoFunction>> autoHandling;
当我序列化对象时,我得到了这个:
"autoHandling" : [ "java.util.HashMap", {
} ],
此Map的键是自定义对象:
public class AutoHandlingSlotKey implements Serializable {
private FunctionalArea slot; // ENUM
private String returnView; // ENUM
所以,我不确定如何纠正我在反序列化对象时遇到的这个问题:
org.codehaus.jackson.map.JsonMappingException: Can not find a (Map) Key deserializer for type [simple type, class com.comcast.ivr.core.domain.AutoHandlingSlotKey]
如果 NOT 有权访问要修改的域对象,有人可以帮助我了解如何解决此问题吗?
答案 0 :(得分:23)
这是很久以前的问题,并且是查找错误时的第一个google结果,但是接受的答案没有代码,可能会让杰克逊初学者(我)感到困惑。我最终找到了帮助的this answer。
因此,正如已接受的答案中所述,实现和注册“密钥解串器”是可行的方法。你可以这样做。
SimpleModule simpleModule = new SimpleModule();
simpleModule.addKeyDeserializer(YourClass.class, new YourClassKeyDeserializer());
objectMapper.registerModule(simpleModule);
对于课程,你所要做的就是:
class YourClassKeyDeserializer extends KeyDeserializer
{
@Override
public Object deserializeKey(final String key, final DeserializationContext ctxt ) throws IOException, JsonProcessingException
{
return null; // replace null with your logic
}
}
就是这样!没有类的注释,没有地图的自定义反序列化器等。
答案 1 :(得分:20)
默认情况下,Jackson尝试将Java Maps序列化为JSON对象(键/值对),因此Map键对象必须以某种方式序列化为String;并且必须有匹配(和注册)密钥解串器。默认配置仅支持一小组JDK类型(字符串,数字,枚举)。 因此mapper不知道如何获取String并从中创建AutoHandlingSlotKey。 (事实上,我很惊讶序列化器没有因为同样的原因而失败)
解决这个问题的两个明显方法是:
在你的情况下,做前者可能更容易。您可能还希望实现自定义密钥序列化程序,以确保密钥是正确格式的序列化程序。
注册序列化器和反序列化器的最简单方法是在Jackson 1.7中添加Module interface(并在1.8中扩展以支持关键序列化器/反序列化器)。