Spring MVC:@RequestBody VS @ModelAttribute

时间:2017-05-01 09:11:28

标签: spring spring-mvc data-binding annotations

我是否理解为了在Spring MVC应用程序中捕获/数据绑定HTTP请求的 body ,somone可以使用...

@RequestBody

对于编码为application/json的请求?

@PostMapping(consumes = "application/json")
public String handleUpload( @RequestBody UploadCommand command ) {
     // ...   
}

@ModelAttribute

对于编码为x-www-form-urlencodedmultipart/form-data的请求?

@PostMapping(consumes = "multipart/form-data")
public String handleUpload( @ModelAttribute UploadCommand command ) {
     // ...   
}

问题:

为什么Spring需要这两个不同的注释?

这些注释是否还有其他用例?

注意: 挖掘之后:这个stackoverflow的答案详细阐述了@ModelAttribute: @ModelAttribute annotation, when to use it?

1 个答案:

答案 0 :(得分:1)

Why is it necessary for Spring to have those two different annotations?

为不同的应用程序类型创建了两个注释。
-@RequestBody用于Restfull应用程序
-用于Web MVC应用程序的@ModelAttribute

它们有什么区别?

假设您有一个Java类UserData:

public class UserData {

    private String firstName;
    private String lastName;

    //...getters and setters
} 

您要使用此用户数据使用请求并映射到您的对象字段。

@RequestBody 用于使用请求正文并通过HttpMessageConverter反序列化为Object。您可以通过在此批注中指定“消耗”来提供@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

所有数据将由spring自动转换。

参考: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>

此表单将由网络浏览器转换为春季将使用的以下请求:

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 ) {
     // ...   
}