2

I'm working on a Spring MVC application and have a client that I have no control over. This client is POSTing JSON data but transmitting a application/x-www-form-urlencoded header. Spring naturally trusts this header and tries to receive the data but can't because its JSON. Has anyone had experience overriding the header that Spring receives or just specifying exactly what type of data is coming, regardless of the headers?

rreichel
  • 794
  • 3
  • 9
  • 25

2 Answers2

1

You can do two things;

  1. Change the client to send the Content-Type: application/json header
  2. Write a Servlet Filter or Spring Interceptor which is on top of the Spring Controller and checks for the header Content-Type. If it is not application/json then it changes it to application/json.
shazin
  • 21,379
  • 3
  • 54
  • 71
  • 2
    3. Read the payload manually, by adding parameter of type `HttpServletRequest`, or `Reader`, or `InputStream`, or `@RequestBody String`, or ... – Andreas Jul 21 '17 at 06:00
  • Thanks! I ended up going the `@RequestBody String` route as it fit my use case best! – rreichel Jul 25 '17 at 01:55
  • 1
    I have tried to go with suggestion 2. But the HttpServletRequest is not mutable when it comes to headers and I tried to wrap it in one of mine and override the header but still. Any examples on how to do 2? – idipous Mar 15 '19 at 21:27
  • You also need to override HttpServletRequest and a whole lot of things. – Sachin Verma Jul 08 '19 at 12:37
0

Why don't you write a separate controller to handle application/x-www-form-urlencoded requests. If the request is a valid JSON, then you can parse it and forward it to to appropriate service.

This way you can also handle a case in future where you get request of same type which is not a valid JSON.

@RequestMapping(value = "/handleURLEncoded", method = RequestMethod.POST, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public @ResponseBody Object handleURLEncoded(HttpEntity<String> httpEntity) {
    String json = httpEntity.getBody();
    //now you have your request as a String
    //you can manipulate it in any way

    if(isJSONValid(json)) {
        JSONObject jsonObj = new JSONObject(json);
        //forward request or call service directly from here
        //...
    }

    //other cases where it's not a valid JSON
}

Note: isJSONValid() method copied from this answer

Raman Sahasi
  • 30,180
  • 9
  • 58
  • 71