1

I want to implement a POST endpoint where it is possible to accept or refuse programmatically the data sent, depending if it comes from querystring or from x-www-form-urlencoded data. I mean:

@PostMapping(value="/api/signin")
ResponseEntity<SigninResponse> signin(
     @RequestParam(value = "username", required = false) String username,
     @RequestParam(value = "password", required = false) String password,
     @RequestBody(required = false) @ModelAttribute SigninRequest sr) {
        // here if I POST a SigninRequest without queryString, aka
        // user/pass sent in x-www-form-urlencoded, both sr and 
        // username+password vars are filled. The same, if I send 
        // username+password on querystring, without any data 
        // on x-www-form-urlencoded, also sr is filled
     }

If I remove the "@ModelAttribute", the POST with querystring works, but the one with x-www-form-urlencoded raises an exception "Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported" (why?) and returns a 415 (Unsupported Media Type).

Anyway, I'm looking for a way to understand when the POST data comes from querystring and when the data comes from x-www-form-urlencoded, to enable/disable programmatically one way vs. the other. I can eventually write two different methods (both in POST), it is not needed to use just one.

Any suggestion?

Thank you.

Sampisa
  • 1,487
  • 2
  • 20
  • 28
  • why would you want to send username and password in the query param? – Chetra_S11 Jan 26 '23 at 07:29
  • I have to remove an old API where user+pass were sent in querystring, but I need to introduce a "grace time" where both options are available; if someone still sends credentials via querystring, I log it and I'll contact him to remind the grace time expiration. So it's just a temporary situation. Apart from that info, not fundamental to the answer, I need to recognise when data is sent via empty POST with data in querystring, or full POST via x-www-form-urlencoded without querystring data. I recognise the json submission, but I still need the "old-fashioned" POST submission recognition. – Sampisa Feb 08 '23 at 16:33

2 Answers2

0

Why you use @RequestBody and @ModelAttribute with your arg at the same time?

You can use @ModelAttribute(binding=false) instead of required=false.

That should help: (Spring: @ModelAttribute VS @RequestBody)

Tip: I don't think is a good practice to include password in querystring.

dr34mer
  • 1
  • 2
  • I use both since I don't know how to solve my problem, that's why I'm asking. Anyway, sorry, but neither ModelAttribute nor RequestBody support "binding=false", what do you mean? – Sampisa Feb 08 '23 at 16:53
0

By default, RequestBody doesn't support application/x-www-form-urlencoded. If you're sending data from a form, its media type will be application/x-www-form-urlencoded which is not supported by RequestBody. RequestBody supports other types such as application/json. @ModelAttribute is like telling Spring you are serializing SigninRequest from a request with application/x-www-form-urlencoded media type.

More info here: Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported for @RequestBody MultiValueMap

Chetra_S11
  • 66
  • 6
  • Sorry, I didn't understand how I can solve my issue. I just need to understand when the same API is invoked passing parameters in querystring with an empty POST and when such POST is filled by the same parameters. Please can you be more specific? How can I split the API in two (one for querystring and one for post), or recognise the invocation? – Sampisa Feb 08 '23 at 16:39