我有许多带有 JAXB 注释的实体,我想使用消息转换器将它们转换为 JSON。
我知道我的读取 JAXB 注释的 ObjectMapper 有效:
String correctJsonText = jacksonObjectMapper.writeValueAsString(entityWithJAXB);
但是当我调用我的休息服务时,默认注册的 MappingJacksonHttpMessageConverter(未配置为读取 JAXB)似乎接管了 - 当 @XmlTransient 被忽略时,由于循环引用导致堆栈溢出......
如何配置 Spring 以使用 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>
休息服务
@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>
无效。
事实证明,我使用 MockMcv 进行的单元测试总是加载默认的处理程序适配器,因此忽略了我的自定义对象映射器。由于方便,我只使用 junit test 测试了控制器,因为它很好地击中了控制器,我不认为这是一个可能的错误原因......
我还没有找到测试的修复方法,但是当我使用 curl 调用服务时,一切正常!
更新/最终解决方案
刚刚为我的测试设置找到了解决方案;使用 MockMvc (spring-test-mvc) 时,您必须明确指定自定义消息转换器:
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 的副本。