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 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.
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);
}