带有JAXB注释的Spring 3.1.2中的注册器MappingJackson2HttpMessageConverter [英] Registrer MappingJackson2HttpMessageConverter in Spring 3.1.2 with JAXB annotations

查看:236
本文介绍了带有JAXB注释的Spring 3.1.2中的注册器MappingJackson2HttpMessageConverter的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有许多带有JAXB注释的实体,我想使用消息转换器将其转换为JSON。

I have a number of entities with JAXB annotations that I would like to convert to JSON using a message-converter.

我知道我的ObjectMapper读取了JAXB注释有效:

I know that my ObjectMapper that reads the JAXB annotations works:

String correctJsonText = jacksonObjectMapper.writeValueAsString(entityWithJAXB); 

但当我调用我的休息服务时,默认注册的MappingJacksonHttpMessageConverter(未配置为读取JAXB)似乎接管 - 当忽略@XmlTransient时,由于循环引用导致堆栈溢出...

But when i call my rest service the default registered MappingJacksonHttpMessageConverter (which is not configured for reading JAXB) seems to take over - resulting in a stackoverflow due to cyclic references when @XmlTransient is ignored...

如何配置Spring以使用MappingJackson2HttpMessageConverter?

How do i configure Spring to use MappingJackson2HttpMessageConverter ?

当前配置

<mvc:annotation-driven>
    <mvc:message-converters register-defaults="false">
        <bean id="jacksonMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
            <property name="objectMapper" ref="jacksonObjectMapper" />
            <property name="supportedMediaTypes">
                <list>
                    <bean class="org.springframework.http.MediaType">
                        <constructor-arg index="0" value="application" />
                        <constructor-arg index="1" value="json" />
                        <constructor-arg index="2" value="UTF-8" />
                    </bean>
                </list>
            </property>

        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>

<bean id="jaxbAnnotationInspector" class="com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector" />

<bean id="jacksonObjectMapper" class="com.fasterxml.jackson.databind.ObjectMapper">
    <property name="annotationIntrospector" ref="jaxbAnnotationInspector" />
</bean>

REST服务

@RequestMapping(value="/{id}", method=RequestMethod.GET, produces = "application/json;charset=UTF-8")
public @ResponseBody EntityWithJAXB readEntityWithJAXB(@PathVariable int id, Model model) {
    return entityService.getById(id);
}

依赖关系

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.0.5</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.0.5</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.module</groupId>
    <artifactId>jackson-module-jaxb-annotations</artifactId>
    <version>2.0.5</version>
</dependency>

更新/解决方案

通过调试我的上下文,我可以看到< mvc:annotation-driven> 中的配置无效。

By debugging my context I could see that the configuration in <mvc:annotation-driven> had no effect.

事实证明我的MockMcv单元测试总是加载默认的handleradapters,因此忽略了我的自定义objectmapper。由于方便,我只使用junit测试对控制器进行了测试,因为它很好地控制了控制器我没想到这是一个可能的错误原因......

It turned out that my unit test with MockMcv always loaded the default handleradapters, thus ignoring my custom objectmapper. Due to convenience I only tested the controller using junit test, since it hit the controller just fine I did not think of this as a probable error cause...

我做了还没找到我测试的修复程序,但是当我使用curl调用服务时一切正常!

I did not find a fix for my test yet, but when I call the service using curl everything works!

UPDATE / Final solution

刚刚为我的测试设置找到了解决方案;使用MockMvc(spring-test-mvc)时,必须明确指定自定义消息转换器:

Just found a solution for my test setup; when using MockMvc (spring-test-mvc) you must specify custom message-converters explicit:

private MockMvc mockMvc;

@Autowired
private MappingJackson2HttpMessageConverter jacksonMessageConverter;

@Autowired
private RestController restController;

@Before
public void initMockMvc(){
    mockMvc = MockMvcBuilders.standaloneSetup(restController)
            .setMessageConverters(jacksonMessageConverter).build();
} 

@Test
public void testRestController() throws Exception{
    DefaultRequestBuilder requestBuilder = MockMvcRequestBuilders.get("/json/42");
    this.mockMvc.perform(requestBuilder).andDo(print()).andExpect(status().isOk());
}

唯一剩下的问题是 jacksonMessageConverter 在以下JIRA解决之前无法直接自动装配: https:// jira .springsource.org /浏览/ SPR-9469 。在那之前,我刚刚在我的测试环境中创建了jacksonMessageConverter的副本。

The only remaining issue is that the jacksonMessageConverter can't be autowired directly until the following JIRA is resolved: https://jira.springsource.org/browse/SPR-9469. Until then, I have just created a copy of the jacksonMessageConverter in my test context.

推荐答案

我复制了你的配置,它完美地工作为了我。默认消息转换器不应生效,因为您已明确指定 register-defaults = false 属性。这就是我的@XmlTransient注释的外观:

I replicated your configuration and it works perfectly for me. The default message converters should not take effect, as you have explicitly specified the register-defaults=false attribute. This is how my @XmlTransient annotation looks:

@XmlAccessorType(XmlAccessType.FIELD)
public class EntityWithJAXB {


    @XmlTransient
    private EntityWithJAXB aChild;

这篇关于带有JAXB注释的Spring 3.1.2中的注册器MappingJackson2HttpMessageConverter的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆