2012-06-28 161 views
12

非字符串映射键我有机管局地图,看起来像这样:反序列化与杰克逊

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]

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

谢谢你的帮助。

+0

作品有你读http://stackoverflow.com/questions/6371092/can-not-find-a-map-key-deserializer-for-type -simple-type-class-com-comcast-i?他的情况看起来与你的一见钟情。 – fvu

+0

是的,我已经阅读过,但实际上我没有找到答案。我怎样才能使用模块来解决这个问题? – Max

回答

3

建立在answer given here上,建议使用解串器实现模块我参考the Jackson Module documentationJodaTime Module是一个容易理解的包含序列化器和解串器的模块的完整示例。

请注意,模块功能是在杰克逊版本1.7中引入的,因此您可能需要升级。

所以一步一步:

  1. 创建基于乔达例如包含相关类的(反)序列化模块
  2. 注册mapper.registerModule(module);

,你会认为模块全部设置

+0

太棒了!非常感谢。 – Max

+2

还有一个附加说明:您需要添加的是“键(解)序列化程序”:由于Map键具有其他限制,常规(de)序列化程序无法按原样使用。但是可以肯定地从模块完成注册。 – StaxMan

+3

@Max您是否可以提供如何实现解串器的代码?我希望看到,如果可能=) – Ted

8

如上所述,诀窍是你需要一个解串器(this也抓到我了)。在我的情况下,在我的类上配置了一个非String映射键,但它并不在我解析的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()); 
13

经过一天的搜索,我发现了一个更简单的方法,它基于this question。解决方案是将@JsonDeserialize(keyUsing = YourCustomDeserializer.class)注释添加到地图。然后通过扩展KeyDeserializer并覆盖deserializeKey方法来实现您的自定义解串器。该方法将使用字符串键调用,您可以使用该字符串构建真实对象,甚至可以从数据库中获取现有对象。

所以先在地图声明:

@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

+0

我一直在试图把注释放在关键类本身(在你的情况下是'Verb'),而不是在地图声明上。你救了我更多的头挠,谢谢! – snappieT