How/Why 参数绑定在没有@RequestParam 的情况下是否有效?

How/Why does parameter binding work without @RequestParam?

我有一个这样声明的端点

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

当我提出类似 /shoebox?color=blue&size=small

的请求时

它正确地将 colorsize 绑定到一个新的 ShoeBox 对象。

但是如果我像这样 @RequestParam delcare

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

然后我得到这个错误

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

我有点理解为什么它不能与 @RequestParam 一起工作,因为我没有使用单个参数,但我不明白的是为什么它在没有任何注释的情况下工作。它怎么知道要绑定它?是否在任何地方记录了此功能?

如果参数不加注解,谁来解决?

就是这个 RequestParamMethodArgumentResolver 文档说:

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.

这就是它起作用的原因。