3

I have an endpoint declared like this

@GetMapping("/shoebox")
public ResponseEntity<?> find(ShoeBox shoebox) {
    ...
}    

When I make a request like /shoebox?color=blue&size=small

It correctly binds color and size to a new ShoeBox object.

But if I delcare with @RequestParam like this

@GetMapping("/shoebox")
public ResponseEntity<?> find(@RequestParam ShoeBox shoebox) {
    ...
}    

Then I get this error

{
    "status": 400,
    "message": "Required request parameter 'shoebox' for method parameter type ShoeBoxis not present",
    "timestamp": 1621373682288,
    "errors": [
        "MissingServletRequestParameterException"
    ]
}

I understand a little of why it doesn't work with @RequestParam because I'm not using a single param, but what I don't understand is why it works without any annotation at all. How does it know to bind it? Is this functionality documented anywhere?

secondbreakfast
  • 4,194
  • 5
  • 47
  • 101

1 Answers1

1

Who is in charge of solving if you do not place any annotation on parameters?

It is this RequestParamMethodArgumentResolver the documentation says:

Resolves method arguments annotated with @RequestParam, arguments of type MultipartFile in conjunction with Spring's MultipartResolver abstraction, and arguments of type javax.servlet.http.Part in conjunction with Servlet 3.0 multipart requests. This resolver can also be created in default resolution mode in which simple types (int, long, etc.) not annotated with @RequestParam are also treated as request parameters with the parameter name derived from the argument name. If the method parameter type is Map, the name specified in the annotation is used to resolve the request parameter String value. The value is then converted to a Map via type conversion assuming a suitable Converter or PropertyEditor has been registered. Or if a request parameter name is not specified the RequestParamMapMethodArgumentResolver is used instead to provide access to all request parameters in the form of a map.

A WebDataBinder is invoked to apply type conversion to resolved request header values that don't yet match the method parameter type.

So that is the reason why it works.

Jonathan JOhx
  • 5,784
  • 2
  • 17
  • 33