2012-03-01 50 views
2

我有一个Spring MVC及其json支持问题。我做了一个Ajax调用来获取一些数据,我想以包含根值的json格式获取这些数据。我也在实体中使用JABX注释,因为这些注释用于某些REST APISpring MVC和Jackson映射不会返回json中的根元素

我已阅读,获得包含Jackson根值,我应该用这个方法:

this.configure(org.codehaus.jackson.map.DeserializationConfig.Feature.UNWRAP_ROOT_VALUE, true); 

所以我创建了一个objectMapper它扩展了Codehaus的一个,看起来像这样:

public class JaxbJacksonObjectMapper extends ObjectMapper { 

    public JaxbJacksonObjectMapper() { 
     final AnnotationIntrospector introspector = new JaxbAnnotationIntrospector(); 

     this.configure(org.codehaus.jackson.map.DeserializationConfig.Feature.UNWRAP_ROOT_VALUE, true); 
     super.getDeserializationConfig().withAnnotationIntrospector(introspector); 

     this.configure(org.codehaus.jackson.map.SerializationConfig.Feature.WRAP_ROOT_VALUE, true); 
     super.getSerializationConfig().withAnnotationIntrospector(introspector); 
    } 
} 

对于Spring使用这个映射器我已经配置了下面几行:

<beans:bean id="customObjectMapper" class="com.test.package.config.JaxbJacksonObjectMapper" /> 

<beans:bean id="jsonMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"> 
    <beans:property name="objectMapper" ref="customObjectMapper" /> 
</beans:bean> 

<beans:bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"> 
    <beans:property name="messageConverters"> 
     <beans:list> 
      <beans:ref bean="jsonMessageConverter"/> 
     </beans:list> 
    </beans:property> 
</beans:bean> 

而且我的实体是这样的:

@XmlRootElement(name = "collection") 
public class Issuers { 
    private List<Issuer> issuers; 
} 

的问题是,当Spring 3.1返回发行人JSON对象的浏览器,它不包括collection根元素。

任何想法如何解决这个问题?

谢谢!

+0

http://stackoverflow.com/q/2435527/923560讨论了类似的挑战 – Abdull 2013-04-23 00:55:02

+0

如果您能够解决这个问题,请让我们知道你做了什么! – Marco 2014-02-14 09:31:16

回答

0

将您的“发行者”包装在通用持有者对象中。这就是我在与Jackson和Spring合作时所做的。

class JSONResponse { 

    private Object collection; 

    public JSONResponse(Object collection) { 
     this.collection = collection; 
    } 
    public Object getCollection() { 
     return collection; 
    } 
} 

...

@RequestMappin(...) 
@ResponseBody 
public Object someHandler(...) { 
    ... 
    return new JSONResponse(issuers); 
} 
+0

这可能是一种选择,谢谢。但我希望得到一个更清晰的解决方案,这样我就不需要在每一个请求中改变它。但在最坏的情况下...... – 2012-03-01 13:47:50

+0

似乎春天的配置不对。这并没有覆盖信息转换器,所以它没有采用我编写的Mapper。 要覆盖那些,右弹簧配置为: ' <注解驱动> <消息变频器> <豆:豆类=“org.springframework.http.converter.json.MappingJacksonHttpMessageConverter”> <豆:属性名=“objectMapper” REF =“customObjectMapper” /> ' 2012-03-01 14:52:42

+0

现在我正在根元素,但它没有采取在给定的名称jabx注释,但类的名称。 任何想法如何解决这个问题?这必须与我创建的杰克逊映射器中的一些问题有关... – 2012-03-01 14:52:51

0

看来,在Spring的配置是不正确的。这并没有覆盖信息转换器,所以它没有采用我编写的Mapper。

要覆盖那些,右弹簧的配置是:

<annotation-driven> 
    <message-converters> 
     <beans:bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"> 
      <beans:property name="objectMapper" ref="customObjectMapper" /> 
     </beans:bean> 
    </message-converters> 
</annotation-driven> 

现在我得到的根元素,但它没有采取在jabx注释给出的名称,但类的名称。

看来,新方法(withAnnotiationIntrospector)不能正常工作,或者我失去了一些东西。但是,如果使用已弃用的名称,我将获得JABX标签中定义的正确根名称。

public JaxbJacksonObjectMapper() { 
    final AnnotationIntrospector introspector = new JaxbAnnotationIntrospector(); 

    this.configure(org.codehaus.jackson.map.SerializationConfig.Feature.WRAP_ROOT_VALUE, true); 
    this.configure(org.codehaus.jackson.map.DeserializationConfig.Feature.UNWRAP_ROOT_VALUE, true); 

    // When using the non deprecated method (withAnnotationIntrospector), 
    // there are problems with JAXB/JSON parser so don't use right now 

    super.getDeserializationConfig().setAnnotationIntrospector(introspector); 
    super.getSerializationConfig().setAnnotationIntrospector(introspector); 
} 
3

看来这个方法withAnnotiationIntrospector没有设置AnnotiationIntrospector。这是返回new DeserializationConfig/SerializationConfig对象,而不是(正确的AnnotiationIntrospector)。

所以,我的版本的JaxbJacksonObjectMapper

public class JaxbJacksonObjectMapper extends ObjectMapper { 

    public JaxbJacksonObjectMapper() { 
     super(); 

     final AnnotationIntrospector introspector = new JaxbAnnotationIntrospector(); 

     this.configure(org.codehaus.jackson.map.DeserializationConfig.Feature.UNWRAP_ROOT_VALUE, true); 
     this.configure(org.codehaus.jackson.map.SerializationConfig.Feature.WRAP_ROOT_VALUE, true); 

     this.setDeserializationConfig(this.getDeserializationConfig().withAnnotationIntrospector(introspector)); 
     this.setSerializationConfig(this.getSerializationConfig().withAnnotationIntrospector(introspector)); 

    } 
} 

现在支持@XmlRootElement@XmlTransient等。

0

对此可替代的使用以下一个声明:

setAnnotationIntrospector(introspector); 

,而不是下面的两个语句,

super.getDeserializationConfig().setAnnotationIntrospector(introspector); 
super.getSerializationConfig().setAnnotationIntrospector(introspector);