Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jackson-dataformat-xml turns @ResponseBody to XML

So I had a perfectly working Spring app. Most of my controller methods are for ajax calls that return JSON via @ResponseBody with the jackson api and returns my Java POJO to JSON.

I have a need to turn XML to JSON, so I find that Jackson has a tool for that, and I add this to my POM to use the library:

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

So that I may use this:

    XmlMapper xmlMapper = new XmlMapper();
    JsonNode node = xmlMapper.readTree(sb.toString().getBytes());

But now the @ResponseBody is returning XML and not JSON. I Remove the dependency and the controllers return JSON again.

Any way to get both? I want the xmlMapper, and JSON from the response body.

like image 676
mmaceachran Avatar asked Feb 06 '18 16:02

mmaceachran


2 Answers

jackson-dataformat-xml appears to be registering a MappingJackson2HttpMessageConverter with a XmlMapper, along with other HttpMessageConverters that work with XML. If you always intended to return JSON from your controllers, you can change what HttpMessageConverter your app uses by overriding configureMessageConverters

For Spring 5.0 and above,

@Configuration
public class HttpResponseConfig implements WebMvcConfigurer {

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.removeIf(converter -> supportsXml(converter) || hasXmlMapper(converter));
    }

    private boolean supportsXml(HttpMessageConverter<?> converter) {
        return converter.getSupportedMediaTypes().stream()
            .map(MimeType::getSubtype)
            .anyMatch(subType -> subType.equalsIgnoreCase("xml"));
    }

    private boolean hasXmlMapper(HttpMessageConverter<?> converter) {
        return converter instanceof MappingJackson2HttpMessageConverter
                && ((MappingJackson2HttpMessageConverter)converter).getObjectMapper().getClass().equals(XmlMapper.class);
    }

}

For older versions of Spring, replace implements WebMvcConfigurer with extends WebMvcConfigurerAdapter

like image 112
kmek Avatar answered Oct 19 '22 19:10

kmek


Add:

Accept: application / json

to the request HTTP header.

Reference: REST API - Use the "Accept: application/json" HTTP Header

like image 2
Ali Avatar answered Oct 19 '22 19:10

Ali