I'm using Spring boot 2.1.3-RELEASE. In my RestController I'm trying to set up a PUT method with one PathVariable and a RequestParam (application/x-www-form-urlencoded). However when I call it the response is a bad request because the required RequestParam is not present.
I tried changing PutMapping to RequestMapping, swapping parameters position and using the syntax @RequestParam(value="param2", required=false) but nothing changes.
Curiously using PostMapping works. Also removing PathVariable works.
Here is the RestController code:
@PutMapping(value="/myurl/{param1}", consumes=MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public String myMethod( @PathVariable("param1") Integer param1, @RequestParam("param2") String param2);
I call the method in this way:
curl -X PUT \
http://localhost:8080/myurl/42 \
-H 'Accept: application/json' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'param2=myparam2value'
The response is:
{ "timestamp": 1553613278534, "status": 400, "error": "Bad Request", "message": "Required String parameter 'param2' is not present", "path": "/myurl/42" }
I expect that PUT works just like POST, but it seems not to.
Unfortunately I cannot send parameters as QueryParam, so I should maintain the same request call because I am refactoring an existing endpoint that works exactly this way.
Thanks
EDIT
I found this is caused by using an HandlerInterceptorAdapter (via WebMvcConfigurer). For some reason, around
org.springframework.web.util.ContentCachingRequestWrapper.getParameterValues
org.apache.coyote.Request.parameters has no content and an exception is thrown, so it works only for POST and not for PUT (GET are handled differently).
I appreciate if someone can suggest if this can be reported as a bug considering that removing the interceptor made it work.
Regards