找不到[简单类型,类com.comcast.ivr.core.domain.AutoHandlingSlotKey]类型的(Map)密钥反序列化器

Mic*_*son 41 java json jackson deserialization

我有一个具有Map的域对象:

private Map<AutoHandlingSlotKey, LinkedHashSet<AutoFunction>> autoHandling;
Run Code Online (Sandbox Code Playgroud)

当我序列化对象时,我得到了这个:

"autoHandling" : [ "java.util.HashMap", {
} ],
Run Code Online (Sandbox Code Playgroud)

这个Map的关键是一个自定义对象:

public class AutoHandlingSlotKey implements Serializable {
    private FunctionalArea slot; // ENUM
    private String returnView;   // ENUM
Run Code Online (Sandbox Code Playgroud)

所以,我不确定如何纠正我在反序列化对象时遇到的这个问题:

org.codehaus.jackson.map.JsonMappingException: Can not find a (Map) Key deserializer for type [simple type, class com.comcast.ivr.core.domain.AutoHandlingSlotKey]
Run Code Online (Sandbox Code Playgroud)

如果我没有访问域对象进行修改,有人可以帮助我理解如何纠正这个问题吗?

est*_*nrv 28

这是很久以前的问题,并且是查找错误时的第一个谷歌搜索结果,但是接受的答案没有代码,可能会让杰克逊初学者(我)感到困惑.我最终发现这个答案有所帮助.

因此,正如已接受的答案中所述,实现和注册"密钥解串器"是可行的方法.你可以这样做.

SimpleModule simpleModule = new SimpleModule();
simpleModule.addKeyDeserializer(YourClass.class, new YourClassKeyDeserializer());
objectMapper.registerModule(simpleModule);
Run Code Online (Sandbox Code Playgroud)

对于课程,您所要做的就是:

class YourClassKeyDeserializer extends KeyDeserializer
{
    @Override
    public Object deserializeKey(final String key, final DeserializationContext ctxt ) throws IOException, JsonProcessingException
    {
        return null; // replace null with your logic
    }
}
Run Code Online (Sandbox Code Playgroud)

而已!类上没有注释,没有地图的自定义反序列化器等.


Sta*_*Man 22

默认情况下,Jackson尝试将Java Maps序列化为JSON对象(键/值对),因此Map键对象必须以某种方式序列化为String; 并且必须有匹配(和注册)密钥解串器.默认配置仅支持一小组JDK类型(字符串,数字,枚举).因此mapper不知道如何获取String并从中创建AutoHandlingSlotKey.(事实上​​,我很惊讶序列化器没有因为同样的原因而失败)

解决这个问题的两种明显方法是:

  • 实现并注册"密钥解串器"
  • 为Maps实现并注册自定义反序列化程序.

在你的情况下,做前者可能更容易.您可能还希望实现自定义密钥序列化程序,以确保密钥是正确格式的序列化程序.

注册序列化器和反序列化器的最简单方法是通过在Jackson 1.7中添加的Module接口(并在1.8中扩展以支持关键序列化器/解串器).

  • 如果没有找到其他内容,这就是后备.还有其他选择:例如,如果类型具有公共单字符串参数构造函数,则将使用该构造函数.或者使用`@JsonCreator`注释的单字符串参数工厂方法.这将消除编写和注册自定义密钥解串器的需要. (3认同)
  • 经过快速测试后,我认为键是使用其 toString 方法进行序列化的,这可能通常不是您想要的。创建密钥序列化器似乎是一个不错的选择。 (2认同)
  • 是的,对于序列化器,使用“@JsonValue”应该可以工作,尽管我还没有测试过;对带有关键(反)序列化器的注释的支持存在一些差距。除此之外,自定义密钥序列化器是一个选项,可以全局注册或使用`@JsonSerialize(keyUsing=MyKeySerializer.class`作为类或属性。 (2认同)