2012-09-20 3 views
8

Mam wiele jednostek z adnotacjami JAXB, które chciałbym przekonwertować na JSON przy użyciu konwertera komunikatów.Registrer MappingJackson2HttpMessageConverter na wiosnę 3.1.2 z adnotacjami JAXB

wiem, że moja ObjectMapper że czyta adnotacje JAXB działa:

String correctJsonText = jacksonObjectMapper.writeValueAsString(entityWithJAXB); 

Ale gdy zgłoszę moją usługę reszta domyślna zarejestrowany MappingJacksonHttpMessageConverter (który nie jest skonfigurowany do czytania JAXB) wydaje się przejąć - co skutkuje stackoverflow z powodu cyklicznych odniesień, gdy @XmlTransient jest ignorowany ...

Jak skonfigurować Spring, aby używać MappingJackson2HttpMessageConverter?

aktualnej konfiguracji

<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> 

usług 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); 
} 

Zależności

<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> 

AKTUALIZACJA/Rozwiązanie

Po debugowaniu mojego kontekstu mogłem zauważyć, że konfiguracja w <mvc:annotation-driven> nie przyniosła żadnego efektu.

Okazało się, że mój test jednostkowy z MockMcv zawsze ładował domyślne handleradaptery, ignorując w ten sposób moją niestandardową objectmapper. Ze względu na wygodę testowałem tylko kontroler przy użyciu testu junit, ponieważ trafił on do kontrolera dobrze, nie myślałem o tym jako o prawdopodobnym błędzie ...

Nie znalazłem poprawki do mojego testu, ale kiedy Dzwonię do usługi za pomocą curl wszystko działa!

UPDATE/Ostateczne rozwiązanie

Wystarczy znaleźć rozwiązanie dla mojej konfiguracji testowej; podczas korzystania MockMvc (wiosna-test-MVC) należy określić niestandardowych komunikatów konwertery wyraźne:

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()); 
} 

Jedyny pozostały problemem jest to, że nie można jacksonMessageConverter autowired bezpośrednio aż po JIRA został rozwiązany: https://jira.springsource.org/browse/SPR-9469. Do tego czasu właśnie utworzyłem kopię programu jacksonMessageConverter w kontekście testu.

Odpowiedz

3

Powieliłem konfigurację i działa ona idealnie dla mnie. Domyślne konwertery komunikatów nie powinny zostać zastosowane, ponieważ wyraźnie określono atrybut register-defaults=false. Tak wygląda moja adnotacja @XmlTransient:

@XmlAccessorType(XmlAccessType.FIELD) 
public class EntityWithJAXB { 


    @XmlTransient 
    private EntityWithJAXB aChild; 
+0

Dzięki, to jest cenna informacja! moje adnotacje @Xml są zamiast tego na pobierających i ustawiających, ale nie sądzę, że powinno to mieć znaczenie. To mogą być inne rzeczy w mojej konfiguracji, które niweczą wtedy ... Spróbuję przenieść konfigurację jackson do czystego projektu, aby sprawdzić, czy to działa dla mnie. Napiszę rozwiązanie, gdy je znajdę. – molholm

+1

Wykonałem pracę konfiguracyjną w czystym projekcie, tak jak ty, bez problemów.Podejrzewałem, że problem został spowodowany przez WebServiceMessageReceiverHandlerAdapter, który powoduje, że dispatch-servlet nie ładuje domyślnych adapterów lub innego problemu z konfiguracją, ale tak się nie stało. – molholm

+0

Aktualizuję oryginalny post z rozwiązaniem, dzięki! – molholm