0

When posting an XML object Foo to /foo.xml I can't get path extension view resolution to kick in, but get the error

Unsupported content type: text/plain

Which is a result of not posting any Content-Type headers. But favorPathExtention should remove that need. Any idea why it doesn't?


Controller

@RequestMapping(value="/foo.xml", method=ADD, produces="application/xml")
@ResponseStatus(HttpStatus.OK)
public @ResponseBody Foo add(@RequestBody Foo foo)  {
    return foo;
}

Configuration

@Configuration
@ComponentScan(basePackages="my.pkg.controller")
public class RestWebConfig extends WebMvcConfigurationSupport {

    @Override
    protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(new MarshallingHttpMessageConverter(...));
        converters.add(new MappingJackson2HttpMessageConverter());
    }

    @Override
    protected void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        configurer.favorPathExtension(true)
            .ignoreAcceptHeader(true)
            .useJaf(false)
            .mediaType("json", MediaType.APPLICATION_JSON)
            .mediaType("xml", MediaType.APPLICATION_XML);
    }
}
Johan Sjöberg
  • 47,929
  • 21
  • 130
  • 148
  • 1
    shoudn't just /foo should work instead of /foo.xml in your request mapping? – csn Oct 16 '13 at 20:49
  • I need explicit mappings `/foo.json`, `/foo.xml` and so on since the `json` object is different from the `xml` object. – Johan Sjöberg Oct 16 '13 at 22:16
  • One (less than ideal) solution, http://stackoverflow.com/questions/4471584/in-spring-mvc-how-can-i-set-the-mime-type-header-when-using-responsebody – Johan Sjöberg Oct 17 '13 at 21:42

2 Answers2

1

I think you've misunderstood the purpose of content negotiation.

Content negotiation is for how the response will be generated, not how the request will be parsed.

You get

Unsupported content type: text/plain

because, with @RequestBody, there are no registeredHttpMessageConverter instances that can read the default request content-type of application/octet-stream (or maybe your client uses text/plain). This all happens in the RequestResponseBodyMethodProcessor which handles generating an argument for the parameter annotated with @RequestBody.

If you're going to send XML or JSON in your request body, set the Content-Type.


As for the content negotiation, with your config and request, the DispatcherServlet will attempt to generate a response with content type application/xml. Because of @ResponseBody, you will need an HttpMessageConverter capable of producing such content. Your MarshallingHttpMessageConverter should be enough. If it isn't, you can write your own.

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
0

I solved the problem by adding text/plain as a supported media type to the message converters, something like

@Override
protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();
    List<MediaType> jsonTypes = new ArrayList<>(jsonConverter.getSupportedMediaTypes());
    jsonTypes.add(MediaType.TEXT_PLAIN);
    jsonConverter.setSupportedMediaTypes(jsonTypes);
    converters.add(jsonConverter);
}
Johan Sjöberg
  • 47,929
  • 21
  • 130
  • 148