Search code examples
springspring-bootjackson-dataformat-xml

Spring 5 -jackson-dataformat-xml forces @ResponseBody with XML


I have to work on a legacy spring 5 [not boot] project and I am facing similar problem like this jackson-dataformat-xml turns @ResponseBody to XML So I started using XMLMapper - input is application/text [which is xml string] and out put should json in controllers . But I see as soon as I add dependency

<dependency>
<artifactId>jackson-dataformat-xml</artifactId>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<version>2.10.2</version>
</dependency>

Response no longer seems to be JSON but xml I am not able to figure out what should be done. I need to use xmlmapper to avoid JAXB2 . Any sample configurations. [Java config will also be OK but not to use java 8 lambda functions as it is not used in this legacy [ because we have certain legacy dependencies like checkstyle not upgraded to java 8 in this project .] would help...Let me know.

I have below config currently but i think issue is with dependency . So some tweaking needs to be done in configuration:

@Configuration
public class HttpResponseConfig implements WebMvcConfigurer {

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
        builder.indentOutput(true).dateFormat(new SimpleDateFormat("yyyy-MM-dd"));
        converters.add(new MappingJackson2HttpMessageConverter(builder.build()));
        converters.add(new MappingJackson2XmlHttpMessageConverter(builder.createXmlMapper(true).build()));

    }
}

Solution

  • There were multiple places where I needed to fix . We are also using Apache HTTP Client to call backend services. Responses from those services also got broken [they started retuning xml]. Since it was a common piece of code, I modified "Accept" header with q=1 for json. http.setHeader("Accept","application/json;q=1, text/html;q=0.9, application/xhtml+xml;q=0.9, application/xml;q=0.8, */*;q=0.7");

    Then came Spring controllers which had to be fixed. I had to configure message converters as well as contentnegotiations both

    
    @Configuration
    @EnableWebMvc
    public class HttpResponseConfig implements WebMvcConfigurer {
        @Autowired
        ObjectMapperFactory objectMapperFactory;//custom
    
        @Bean
        public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
            MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
            converter.setObjectMapper(objectMapperFactory.getObjectMapper());
            return converter;
        }
    
        @Override
        public void extendMessageConverters(final List<HttpMessageConverter<?>> converters) {
            converters.add(0, new MappingJackson2HttpMessageConverter(mappingJackson2HttpMessageConverter().getObjectMapper()));
    
        }
    
        @Override
        public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
            configurer.defaultContentType(MediaType.APPLICATION_JSON_UTF8);
        }
    
    }