복붙노트

[SPRING] JAXB 주석이있는 Spring 3.1.2의 등록자 MappingJackson2HttpMessageConverter

SPRING

JAXB 주석이있는 Spring 3.1.2의 등록자 MappingJackson2HttpMessageConverter

메시지 변환기를 사용하여 JSON으로 변환하려는 JAXB 주석이있는 여러 엔티티가 있습니다.

JAXB 주석을 읽는 ObjectMapper가 작동하는 것을 알고 있습니다.

String correctJsonText = jacksonObjectMapper.writeValueAsString(entityWithJAXB); 

하지만 내 휴식 서비스를 호출하면 기본적으로 등록 된 MappingJacksonHttpMessageConverter (JAXB 읽기 용으로 구성되지 않음)이 대신 사용됩니다. @XmlTransient가 무시 될 때 순환 참조로 인해 stackoverflow가 발생합니다 ...

MappingJackson2HttpMessageConverter를 사용하기 위해 Spring을 어떻게 구성합니까?

현재 구성

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

업데이트 / 솔루션

내 컨텍스트를 디버깅하여 의 구성이 아무 효과가 없음을 알 수있었습니다.

MockMcv로 유닛 테스트를 할 때 항상 기본 handleradapters가로드되어 커스텀 objectmapper가 무시되었다. 내가 JUNIT 테스트를 사용하여 컨트롤러를 테스트 한 편의성으로 인해 컨트롤러가 정상적으로 작동했기 때문에이 오류가 발생할 가능성이 있다고 생각하지 않았습니다.

아직 테스트를위한 픽스를 찾지 못했지만, 컬을 사용하여 서비스를 호출하면 모든 것이 작동합니다!

업데이트 / 최종 솔루션

방금 내 테스트 설정에 대한 해결책을 찾았습니다. 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());
}

유일한 문제는 다음 JIRA가 해결 될 때까지 jacksonMessageConverter를 자동으로 자동으로 실행할 수 없다는 것입니다 : https://jira.springsource.org/browse/SPR-9469. 그때까지는 테스트 컨텍스트에서 jacksonMessageConverter의 복사본을 만들었습니다.

해결법

  1. ==============================

    1.귀하의 구성을 복제하고 완벽하게 작동합니다. register-defaults = false 속성을 명시 적으로 지정 했으므로 기본 메시지 변환기가 적용되지 않아야합니다. 이것이 내 @XmlTransient 주석이 보이는 방식입니다.

    귀하의 구성을 복제하고 완벽하게 작동합니다. register-defaults = false 속성을 명시 적으로 지정 했으므로 기본 메시지 변환기가 적용되지 않아야합니다. 이것이 내 @XmlTransient 주석이 보이는 방식입니다.

    @XmlAccessorType(XmlAccessType.FIELD)
    public class EntityWithJAXB {
    
    
        @XmlTransient
        private EntityWithJAXB aChild;
    
  2. from https://stackoverflow.com/questions/12514285/registrer-mappingjackson2httpmessageconverter-in-spring-3-1-2-with-jaxb-annotati by cc-by-sa and MIT license