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

查看:20
本文介绍了带有 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.

我知道读取 JAXB 注释的 ObjectMapper 可以正常工作:

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 进行的单元测试总是加载默认的处理程序适配器,因此忽略了我的自定义对象映射器.由于方便,我只使用 junit test 测试了控制器,因为它很好地击中了控制器,我不认为这是一个可能的错误原因......

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!

更新/最终解决方案

刚刚为我的测试设置找到了解决方案;使用 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/browse/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天全站免登陆