Spring MVC - 为什么不能一起使用@RequestBody和@RequestParam [英] Spring MVC - Why not able to use @RequestBody and @RequestParam together
问题描述
将HTTP开发客户端与帖子请求和内容类型应用程序/ x-www-form-urlencoded一起使用
Using HTTP dev client with Post request and Content-Type application/x-www-form-urlencoded
1)仅@RequestBody
1) Only @RequestBody
请求 - localhost:8080 / SpringMVC / welcome
In Body - name = abc
Request - localhost:8080/SpringMVC/welcome In Body - name=abc
代码 -
@RequestMapping(method = RequestMethod.POST)
public String printWelcome(@RequestBody String body, Model model) {
model.addAttribute("message", body);
return "hello";
}
//按预期为name = abc提供正文
// Gives body as 'name=abc' as expected
2)只有@RequestParam
2) Only @RequestParam
请求 - localhost:8080 / SpringMVC / welcome
In Body - name = abc
Request - localhost:8080/SpringMVC/welcome In Body - name=abc
代码 -
@RequestMapping(method = RequestMethod.POST)
public String printWelcome(@RequestParam String name, Model model) {
model.addAttribute("name", name);
return "hello";
}
//按预期将名称命名为'abc'
// Gives name as 'abc' as expected
3)两者一起
请求 - localhost:8080 / SpringMVC / welcome
In Body - name = abc
Request - localhost:8080/SpringMVC/welcome In Body - name=abc
代码 -
@RequestMapping(method = RequestMethod.POST)
public String printWelcome(@RequestBody String body, @RequestParam String name, Model model) {
model.addAttribute("name", name);
model.addAttribute("message", body);
return "hello";
}
// HTTP错误代码400 - 客户端发送的请求在语法上不正确。
// HTTP Error Code 400 - The request sent by the client was syntactically incorrect.
4)上面的params位置已更改
4) Above with params position changed
请求 - localhost:8080 / SpringMVC / welcome
In Body - name = abc
Request - localhost:8080/SpringMVC/welcome In Body - name=abc
代码 -
@RequestMapping(method = RequestMethod.POST)
public String printWelcome(@RequestParam String name, @RequestBody String body, Model model) {
model.addAttribute("name", name);
model.addAttribute("message", body);
return "hello";
}
//无错误。名字是'abc'。 body是空的
// No Error. Name is 'abc'. body is empty
5)一起但获取类型url参数
5) Together but get type url parameters
请求 - localhost:8080 / SpringMVC / welcome ?name = xyz
In Body - name = abc
Request - localhost:8080/SpringMVC/welcome?name=xyz In Body - name=abc
代码 -
@RequestMapping(method = RequestMethod.POST)
public String printWelcome(@RequestBody String body, @RequestParam String name, Model model) {
model.addAttribute("name", name);
model.addAttribute("message", body);
return "hello";
}
//名称是'xyz',正文是'name = abc'
// name is 'xyz' and body is 'name=abc'
6)与5)相同,但参数位置已更改
6) Same as 5) but with parameters position changed
代码 -
@RequestMapping(method = RequestMethod.POST)
public String printWelcome(@RequestParam String name, @RequestBody String body, Model model) {
model.addAttribute("name", name);
model.addAttribute("message", body);
return "hello";
}
// name ='xyz,abc'body is empty
// name = 'xyz,abc' body is empty
有人可以解释这种行为吗?
Can someone explain this behaviour?
推荐答案
@ RequestBody
javadoc states
The @RequestBody
javadoc states
指示方法参数的注释应该绑定到Web的主体
请求。
Annotation indicating a method parameter should be bound to the body of the web request.
它使用 HttpMessageConverter
的已注册实例将请求正文反序列化为注释参数类型的对象。
It uses registered instances of HttpMessageConverter
to deserialize the request body into an object of the annotated parameter type.
和 @RequestParam
注释,表示方法参数应绑定到
a web request参数。
Annotation which indicates that a method parameter should be bound to a web request parameter.
-
Spring将请求正文绑定到使用
@RequestBody
注释的参数。
Spring将请求体中的请求参数(url编码参数)绑定到方法pa rameter。 Spring将使用参数的名称,即。 name
,用于映射参数。
Spring binds request parameters from the request body (url-encoded parameters) to your method parameter. Spring will use the name of the parameter, ie. name
, to map the parameter.
按顺序解析参数。首先处理 @RequestBody
。 Spring将使用所有 HttpServletRequest
InputStream
。然后,当它尝试解析 @RequestParam
,默认情况下 required
时,查询中没有请求参数字符串或请求体的剩余部分,即。没有。所以它失败了,因为处理程序方法无法正确处理请求。
Parameters are resolved in order. The @RequestBody
is processed first. Spring will consume all the HttpServletRequest
InputStream
. When it then tries to resolve the @RequestParam
, which is by default required
, there is no request parameter in the query string or what remains of the request body, ie. nothing. So it fails with 400 because the request can't be correctly handled by the handler method.
@RequestParam的处理程序
首先行动,阅读 HttpServletRequest
InputStream
可以映射请求参数,即。整个查询字符串/ url编码的参数。它这样做并获得值 abc
映射到参数 name
。当 @RequestBody
的处理程序运行时,请求正文中没有任何内容,因此使用的参数是空字符串。
The handler for @RequestParam
acts first, reading what it can of the HttpServletRequest
InputStream
to map the request parameter, ie. the whole query string/url-encoded parameters. It does so and gets the value abc
mapped to the parameter name
. When the handler for @RequestBody
runs, there's nothing left in the request body, so the argument used is the empty string.
@RequestBody
的处理程序读取正文并将其绑定到参数。然后, @RequestParam
的处理程序可以从URL查询字符串中获取请求参数。
The handler for @RequestBody
reads the body and binds it to the parameter. The handler for @RequestParam
can then get the request parameter from the URL query string.
@RequestParam
的处理程序从正文和URL查询字符串中读取。它通常会将它们放在 Map
中,但由于参数的类型为 String
,因此Spring将序列化将
映射为逗号分隔值。然后, @RequestBody
的处理程序再没有什么可以从正文中读取。
The handler for @RequestParam
reads from both the body and the URL query String. It would usually put them in a Map
, but since the parameter is of type String
, Spring will serialize the Map
as comma separated values. The handler for @RequestBody
then, again, has nothing left to read from the body.
这篇关于Spring MVC - 为什么不能一起使用@RequestBody和@RequestParam的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!