Spring MVC:@RequestBody VS @ModelAttribute [英] Spring MVC: @RequestBody VS @ModelAttribute

查看:36
本文介绍了Spring MVC:@RequestBody VS @ModelAttribute的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Did I understood it correct that in order to catch/data-bind the body of a HTTP Request in a Spring MVC application somone can use...

@RequestBody

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

for requests encoded as application/json?

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

@ModelAttribute

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

for requests encoded as x-www-form-urlencoded or 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?

这些注释还有其他用例吗?

Are there any other use cases for those annotations?

注意:挖掘后:这个stackoverflow答案深入阐述了@ModelAttribute:@ModelAttribute 注解,何时使用?

NOTE: After digging around: This stackoverflow answer elaborates on @ModelAttribute in depth: @ModelAttribute annotation, when to use it?

推荐答案

为什么 Spring 需要有这两种不同的注解?

为不同的应用程序类型创建了两个注释.
- 用于restfull应用程序的@RequestBody
- @ModelAttribute 用于 web mvc 应用程序

Two annotations are created for different application types.
- @RequestBody for restfull applications
- @ModelAttribute for web mvc application

它们有什么区别?

假设您有一个 Java 类 UserData:

Suppose you have a java class UserData:

public class UserData {

    private String firstName;
    private String lastName;

    //...getters and setters
} 

您希望使用具有此用户数据的请求并映射到您的对象字段.

You want to consume requests with this user data and map to your object fields.

@RequestBody 用于消费请求正文并通过 HttpMessageConverter 反序列化为 Object.您可以通过在此注释中指定consumes"来提供@PostMapping 可以接受的数据类型.

@RequestBody is used for consuming request body and to deserialize into an Object through an HttpMessageConverter. You can provide data types that @PostMapping can accept by specifing "consumes" in this annotation.

参考:https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-ann-requestbody

带有用户数据 json 正文的 POST 请求示例:

Example of the POST request with user data json body:

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 来注释您的方法参数,所有数据都将在您的模型中进行转换

You can simply annotate your method argument with annotation @RequestBody and all data will be converted in your model

@PostMapping("/user")
public void getUserData( @RequestBody UserData userData) {
     // ...   
}

否则,您必须将请求作为字符串使用,然后自己手动进行反序列化:

Otherwise, you have to consume your request as string and then manually do deserialization by yourself:

ObjectMapper objectMapper = new ObjectMapper();
UserData userData = objectMapper.readValue(postBody, UserData.class)

@ModelAttribute 是对 ServletRequest 的增强,它使您不必处理解析和转换单个查询参数和表单字段.您只需使用此注释对请求正文进行注释,无需再执行此操作:

@ModelAttribute is an enhancement for ServletRequest that saves you from having to deal with parsing and converting individual query parameters and form fields. You simply annotate your request body with this annnotation and don't need any more to do this:

String firstName= req.getParameter("firstName"); // req is HttpServletRequest
String lastName= req.getParameter("lastName"); // req is HttpServletRequest

所有数据都会被spring自动转换.

All data will be converted by spring automatically.

参考:https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-ann-modelattrib-method-args

此请求的表单示例如下:

Example of the form for this request is following:

<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 将使用的以下请求:

This form will be converted by web browser to the following request that will be consumbed by spring:

POST / HTTP/2.0
Host: foo.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 13

firstName=Tyrion&lastName=Lannister

spring mvc 控制器示例:

Example of spring mvc controller:

@PostMapping("/user")
public void getUserData( @ModelAttribute UserData userData ) {
     // ...   
}

这篇关于Spring MVC:@RequestBody VS @ModelAttribute的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆