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);
}
}
I solved the problem by adding
text/plain
as a supported media type to the message converters, something likeI 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
because, with
@RequestBody
, there are no registeredHttpMessageConverter
instances that can read the default request content-type ofapplication/octet-stream
(or maybe your client usestext/plain
). This all happens in theRequestResponseBodyMethodProcessor
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 typeapplication/xml
. Because of@ResponseBody
, you will need anHttpMessageConverter
capable of producing such content. YourMarshallingHttpMessageConverter
should be enough. If it isn't, you can write your own.