2012-01-03 43 views
4

我有几个扩展LinkedHashMap<String, Object>的模型类:它们定义包含Map的get和put方法的getter和setter。我试图用Jackson(带RESTEasy)序列化这些类的实例,但Jackson拒绝关注我的获得者,这些获得者用@JsonProperty注释。相反,它只是序列化背景地图的键值对。我尝试使用@JsonAutoDetect来禁用所有方法和字段的自动检测,但这并没有改变任何内容。有没有一种方法可以防止Jackson自动序列化一个Map,或者是否必须创建不延伸LinkedHashMap<String, Object>的新模型类?杰克逊 - 序列化时忽略映射超类

回答

7

我具有延伸LinkedHashMap<String, Object>几个模型类:它们定义getter和setter其包装Map的get和put方法

这是当使用继承一个典型的例子:你他发现其他一些代码(即杰克逊)正在将你的类视为其超类的一个实例,而这并不是你想要的。在这些(以及一般情况下)的情况下,通常使用组合而不是继承。

我建议您将模型类重写为包含的地图,而不是扩展一个。您比方式获得更多的控制,并且最终的模型不易变脆。如果您需要将您的模型视为Map,然后实施呈现该视图的asMap方法(或类似的东西)。

+1

感谢您的回复,skaffman。我实际上正在考虑转向基于构图的方法。 'LinkedHashMap'实际上不是我模型类的直接超类;相反,它们扩展了MongoDB的'BasicDBObject',这使我可以轻松地坚持它们。但是,我可能会尝试将这些对象用于太多目的。添加到DBObject()和fromDBObject()方法应该可以工作。不过,我仍然好奇是否有办法阻止Jackson执行默认的“Map”序列化。有没有办法禁用特定类型的序列化程序? – gilby 2012-01-03 22:36:27

9

我同意@ skaffman的回应。但是如果你不能很容易地改变继承结构,那么可能有办法解决这个问题。

一种可能性是,如果你有一个定义getter/setter方法的接口,你可以添加

@JsonSerialize(as=MyInterface.class) 
@JsonDeserialize(as=MyInterface.class) 

这将迫使杰克逊只用不管是通过特定的接口使用。

自定义序列化器/反序列化器也是一种可能性,但这是相当多的工作。

2

您可以实现自己的org.codehaus.jackson.map.DeserializerProvider延伸杰克逊的org.codehaus.jackson.map.deser.StdDeserializerProvider和覆盖方法_createDeserializer

import org.codehaus.jackson.map.SerializerProvider; 
import org.codehaus.jackson.map.deser.StdDeserializerProvider; 
import org.codehaus.jackson.map.DeserializationConfig; 
... 

class MyDeserializerProvider extends StdDeserializerProvider { 

    @Override 
    protected JsonDeserializer<Object> _createDeserializer(DeserializationConfig config, JavaType type, BeanProperty property) throws JsonMappingException { 
     if (type.isMapLikeType()) {  // (1) 
      return this._factory.createBeanDeserializer(config, this, type, property); 
     } else { 
      return super._createDeserializer(config, type, property); 
     } 
    } 
} 

(1)使用,如果条件满足您的需求

定制解串器是在ObjectMapper直接登记:

ObjectMapper om = new ObjectMapper(); 
om.setDeserializerProvider(new MyDeserializerProvider()); 

我用杰克逊1.9.11测试了这个。