2012-09-20 36 views
8

我有大量帶有JAXB註釋的實體,我想使用消息轉換器將其轉換爲JSON。註冊器在Spring 3.1.2中使用JAXB註釋MappingJackson2HttpMessageConverter

我知道,我的ObjectMapper,讀取JAXB註釋的工作原理:

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> 

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>中的配置沒有效果。

事實證明,我的單元測試與MockMcv總是加載默認handleradapters,從而忽略我的自定義objectmapper。由於方便,我只測試控制器使用junit測試,因爲它擊中控制器就好了我沒有想到這是一個可能的錯誤原因...

我沒有找到我的測試修復,但是當我使用curl調用服務一切正常!

UPDATE /最終解決

剛剛發現我的測試設置的解決方案;使用MockMvc(彈簧試驗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的副本。

回答

3

我複製了你的配置,它完全適合我。默認的消息轉換器不會生效,因爲您已明確指定register-defaults=false屬性。這是我的@XmlTransient註釋的外觀:

@XmlAccessorType(XmlAccessType.FIELD) 
public class EntityWithJAXB { 


    @XmlTransient 
    private EntityWithJAXB aChild; 
+0

謝謝,這是有價值的信息!我的@Xml註釋代替了getter和setter,但我認爲這不會有什麼區別。在我的配置中可能還有其他的東西會讓事情變得糟糕......然後我會嘗試將傑克遜配置移動到一個乾淨的項目上,以查看它是否適用於我。我會在找到解決方案時發佈解決方案。 – molholm

+1

我在一個乾淨的項目中完成了配置工作,就像您一樣,沒有問題。我懷疑這個問題是由一個WebServiceMessageReceiverHandlerAdapter引起的,它導致dispatch-servlet不加載默認適配器或其他一些配置問題,但事實並非如此。 – molholm

+0

我用解決方案更新了原始文章,謝謝! – molholm