Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC - Accept JSON when content-type is custom (not application/json)

I am trying to implement the Content-Security-Policy-Report-Only Header for my website. In order to do that, i need a controller that will accept the browsers POST-Request - which will send data about the violation in form of JSON. This request, however, seems to specify the Content-Type as application/csp-report instead of application/json (side note: Why the hell??).

This apparently causes Spring to refuse the request - it seems like the usage of @RequestBody makes spring only accept requests that are of Content-Type "application/json". Even when i specifically set the value consumes of the @RequestMapping annotation to application/csp-report it still does not accept the request.

I have gone as far as using a filter to wrap the request with HttpServletRequestWrapper - which seems to be the common way of modifying the behavior of a request. I have overwritten all of these methods: getContentType(), getHeader(String), getHeaders(String) to return "application/json". But the request still does not go through.

  • What am i missing here?
  • Are there any better solutions to this that do not require me to do magic with the request?
  • I wouldn't even mind parsing the JSON manually, can i somehow accept it as plain String instead?
like image 766
Mercious Avatar asked Mar 03 '17 13:03

Mercious


1 Answers

According documentation on @RequestBody annotation,

The body of the request is passed through an HttpMessageConverter to resolve the method argument depending on the content type of the request

What that means is Spring Framework defines a specialized API for defining how certain MediaTypes are converted into certain Java types when used as parameters to REST endpoints.

Here is a pretty good article showcasing these capabilities.

There are a great deal of builtin Spring converters that you may be able to just configure and use if your media format can be mapped to their respective media formats. Specifically for your case, you should look at one of the converters available in spring.converter.json package. In simplest case, making it work should be as simple as:

HttpMessageConverter converter = new <JsonConverterOfYourChoice>(JsonMapper);

converter.getSupportedMediaTypes().add(new MediaType("application", "csp-report"));

And then registering such converter into a spring's configuration as you do.

Other available converter types include:

  • StringHttpMessageConverter
  • ObjectToStringHttpMessageConverter (if you have already configured Spring's ConversionService to read your desired types from String)
  • ByteArrayHttpMessageConverter
  • FormHttpMessageConverter
  • Various XML-based converters living in spring.converter.xml package
  • AllEncompassingFormHttpMessageConverter (converter built on top of Form converter and capable of handling XML and JSON as well)
  • ProtobufHttpMessageConverter
  • Atom/RSS feed message converters.

Finally, if none of the above does not apply for you, you can make and register your own HttpMessageConverter implementation.

like image 110
M. Prokhorov Avatar answered Nov 06 '22 14:11

M. Prokhorov