2011-09-19 99 views
4

使用Spring 3和Jackson 1.7.6,我可以序列化一个抽象类的实现并输出该类的完全限定名称作为名为@class的属性。当我的Spring控制器从一个用@ResponseBody注释的控制器返回一个实例时,这工作正常。@JsonTypeInfo可以与Collections一起使用吗?

当返回根据所得JSON改变了上述的类型,其类型被序列化(从每个子类字段存在)的Collection,但它不包括@class属性,它我们的客户代码需要。

如何在返回集合时将此类型提示导入序列化的JSON?

//Returns complete with @class=com.package.blah 
@RequestMapping("/json/getProduct.json") 
public @ResponseBody Product getProduct(Integer id) 
{ 
    return service.getProduct(id); 
} 

//Does not include @class 
@RequestMapping("/json/getProducts.json") 
public @ResponseBody List<Product> getProducts() 
{ 
    return service.getProducts(); 
} 

回答

2

为了做到这一点,您需要配置ObjectMapper。这不是直接通过Spring,而是可设置的属性,ObjectMapper具有可调用的方法来设置其状态(然后将其存储为位掩码)。

如果您使用的是<mvc:annotation-driven />,则需要用等效标记替换它,该标记可以在Spring JavaDocs中找到。

扩展ObjectMapper:

public class ConfigurableObjectMapper extends ObjectMapper 
{ 
    public ConfigurableObjectMapper() 
    { 
     this.enableDefaultTypingAsProperty(DefaultTyping.JAVA_LANG_OBJECT, JsonTypeInfo.Id.CLASS.getDefaultPropertyName()); 
    } 
} 

然后告诉Spring使用这个类的一个实例,而不是默认的实现。

<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"> 
    <property name="order" value="0" /> 
</bean> 

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> 
    <property name="webBindingInitializer"> 
     <bean class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer"> 
      <property name="validator" ref="validator" /> 
     </bean> 
    </property> 
    <property name="messageConverters"> 
     <list> 
      <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"> 
       <property name="objectMapper"> 
        <bean class="com.blitzgamesstudios.web.common.json.ConfigurableObjectMapper" /> 
       </property> 
      </bean> 
      <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter" /> 
      <bean class="org.springframework.http.converter.StringHttpMessageConverter" /> 
      <bean class="org.springframework.http.converter.FormHttpMessageConverter" /> 
      <bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter" /> 
     </list> 
    </property> 
</bean> 

<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" /> 
2

每个类使用时,您可以使用@JsonTypeInfo使用POJO,集合和地图,但要注意的集合和地图声明值类型必须是一个拥有(或继承)@JsonTypeInfo注释(@JsonTypeInfo注解)。例如,如果您的类型为“收集” - 在这种情况下,Deejay的答案是正确的,因为您可以使用“默认输入”选项强制收录。

但是,如果你有一个集合属性序列化/反序列化,即东西也应该工作:

public class Bean { 
    @JsonTypeInfo(....) 
    public Collection<Object> listOfObjects; // does work because it's per-property annotation! 
    // ... also, applies to value type and not Collection type itself 
} 

因为这将覆盖任何@JsonTypeInfo标注值类型,否则可能有

相关问题