Spring MVC:@RequestBody VS @ModelAttribute
问题内容:
我是否理解它正确才能在Spring MVC应用程序中捕获/数据绑定HTTP请求的 主体 ,所以somone可以使用…
@RequestBody
对于编码为的请求application/json
?
@PostMapping(consumes = "application/json")
public String handleUpload( @RequestBody UploadCommand command ) {
// ...
}
@ModelAttribute
对于请求编码为x-www-form-urlencoded
或multipart/form-data
?
@PostMapping(consumes = "multipart/form-data")
public String handleUpload( @ModelAttribute UploadCommand command ) {
// ...
}
问题:
为什么Spring有必要具有这两个不同的注释?
这些注释还有其他用例吗?
问题答案:
Why is it necessary for Spring to have those two different annotations?
为不同的应用程序类型创建了两个注释。
-用于Restfull应用程序的@RequestBody-
用于Web MVC应用程序的@ModelAttribute
他们有什么区别?
假设您有一个Java类UserData:
public class UserData {
private String firstName;
private String lastName;
//...getters and setters
}
您想使用此用户数据使用请求并映射到您的对象字段。
@RequestBody 用于使用请求正文,并通过HttpMessageConverter反序列化为Object。您可以通过在此批注中指定“
consums”来提供@PostMapping可以接受的数据类型。
参考:https :
//docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-
ann-requestbody
带有用户数据json主体的POST请求示例:
POST /api/v1/auth HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Content-Length: 40
Accept: application/json, text/plain, */*
Content-Type: application/json
{"firstName":"Tyrion","lastName":"Lannister"}
您可以简单地用注解@RequestBody注释方法参数,所有数据都将在模型中转换
@PostMapping("/user")
public void getUserData( @RequestBody UserData userData) {
// ...
}
否则,您必须将请求作为字符串使用,然后自己手动进行反序列化:
ObjectMapper objectMapper = new ObjectMapper();
UserData userData = objectMapper.readValue(postBody, UserData.class)
@ModelAttribute
是ServletRequest的增强功能,使您不必处理解析和转换单个查询参数和表单字段的麻烦。您只需使用此注释来注释您的请求正文,而无需执行任何其他操作:
String firstName= req.getParameter("firstName"); // req is HttpServletRequest
String lastName= req.getParameter("lastName"); // req is HttpServletRequest
弹簧将自动转换所有数据。
参考:https :
//docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-
ann-modelattrib-method-
args
此请求的表单示例如下:
<form action="yourEndpoint" method="POST">
<input name="firstName" id="firstName" value="Tyrion">
<input name="lastName" id="lastName" value="Lannister">
<button>Submit</button>
</form>
该表单将通过Web浏览器转换为以下请求,该请求将在spring之前完成:
POST / HTTP/2.0
Host: foo.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 13
firstName=Tyrion&lastName=Lannister
Spring MVC控制器的示例:
@PostMapping("/user")
public void getUserData( @ModelAttribute UserData userData ) {
// ...
}