使用 Jackson 反序列化非字符串映射键

2022-09-01 16:45:37

我有一张地图,看起来像这样:

public class VerbResult {
    @JsonProperty("similarVerbs")
    private Map<Verb, List<Verb>> similarVerbs;
}

我的动词类如下所示:

public class Verb extends Word {
    @JsonCreator
    public Verb(@JsonProperty("start") int start, @JsonProperty("length") int length,
            @JsonProperty("type") String type, @JsonProperty("value") VerbInfo value) {
        super(length, length, type, value);
    }
    //...
}

我想序列化和反序列化我的VerbResult类的实例,但是当我这样做时,我得到这个错误:Can not find a (Map) Key deserializer for type [simple type, class my.package.Verb]

我在网上读到,你需要告诉杰克逊如何反序列化地图键,但我没有找到任何解释如何执行此操作的信息。动词类也需要在映射外部进行序列化和反序列化,因此任何解决方案都应保留此功能。

感谢您的帮助。


答案 1

经过一天的搜索,我遇到了一种基于这个问题的更简单的方法。解决方案是将注记添加到地图中。然后,通过扩展和重写该方法实现自定义反序列化程序。该方法将使用字符串键调用,您可以使用该字符串来构建真实对象,甚至可以从数据库中获取现有对象。@JsonDeserialize(keyUsing = YourCustomDeserializer.class)KeyDeserializerdeserializeKey

所以在映射声明中的第一个:

@JsonDeserialize(keyUsing = MyCustomDeserializer.class)
private Map<Verb, List<Verb>> similarVerbs;

然后创建将使用字符串键调用的反序列化程序。

public class MyCustomDeserializer extends KeyDeserializer {
    @Override
    public MyMapKey deserializeKey(String key, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        //Use the string key here to return a real map key object
        return mapKey;
    }
}

适用于泽西岛和杰克逊2.x


答案 2

如上所述,诀窍是你需要一个密钥解串器(这也让我抓了出来)。在我的情况下,在我的类上配置了一个非字符串映射键,但它不在我正在解析的JSON中,因此一个非常简单的解决方案适用于我(只需在键解序列化程序中返回null)。

public class ExampleClassKeyDeserializer extends KeyDeserializer
{
    @Override
    public Object deserializeKey( final String key,
                                  final DeserializationContext ctxt )
       throws IOException, JsonProcessingException
    {
        return null;
    }
}

public class ExampleJacksonModule extends SimpleModule
{
    public ExampleJacksonModule()
    {
        addKeyDeserializer(
            ExampleClass.class,
            new ExampleClassKeyDeserializer() );
    }
}

final ObjectMapper mapper = new ObjectMapper();
mapper.registerModule( new ExampleJacksonModule() );

推荐