我遇到了一个关于Spring MVC及其json支持的问题。我做一个ajax调用来获取一些数据,我想以json格式获取包括根值的数据。我还在实体中使用JABX
注释,因为它们用于某些REST API
。
我已经读过要获取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 :(得分: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
和其他。
答案 1 :(得分: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);
}
答案 2 :(得分:0)
看起来弹簧配置不对。这并没有覆盖messageconverters,所以它没有采用我写的Mapper。
要覆盖它们,正确的spring配置为:
<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 :(得分:0)
在一个陈述之后替代此用法:
setAnnotationIntrospector(introspector);
而是遵循两个陈述,
super.getDeserializationConfig().setAnnotationIntrospector(introspector);
super.getSerializationConfig().setAnnotationIntrospector(introspector);