Spring:@ModelAttribute VS @RequestBody

问题描述 投票:0回答:10

如有错误,请指正。 两者都可用于数据绑定

问题是何时使用@ModelAttribute?

@RequestMapping(value="/owners/{ownerId}/pets/{petId}/edit", method = RequestMethod.POST)
public String processSubmit(@ModelAttribute Pet pet) { }

另外,什么时候使用@RequestBody?

@RequestMapping(value = "/user/savecontact", method = RequestMethod.POST
public String saveContact(@RequestBody Contact contact){ }

根据我的理解,两者都有相似的目的。

谢谢!!

spring spring-mvc data-binding
10个回答
56
投票

我理解的最简单的方法是,

@ModelAttribute
将采用查询字符串。因此,所有数据都通过 url 传递到服务器。

至于

@RequestBody
,所有数据都将通过完整的JSON正文传递到服务器。


22
投票

@ModelAttribute
用于绑定请求参数中的数据(以键值对形式),

但是

@RequestBody
用于绑定整个请求正文中的数据,例如 POST、PUT .. 包含其他格式(例如 json、xml)的请求类型。


16
投票

如果你想上传文件,你必须使用

@ModelAttribute
。对于
@RequestBody
,这是不可能的。示例代码

@RestController
@RequestMapping(ProductController.BASE_URL)
public class ProductController {

    public static final String BASE_URL = "/api/v1/products";

    private ProductService productService;

    public ProductController(ProductService productService) {
        this.productService = productService;
    }

    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public ProductDTO createProduct(@Valid @ModelAttribute ProductInput productInput) {
        return productService.createProduct(productInput);
    }

}

产品输入类

@Data
public class ProductInput {

    @NotEmpty(message = "Please provide a name")
    @Size(min = 2, max = 250, message = "Product name should be minimum 2 character and maximum 250 character")
    private String name;

    @NotEmpty(message = "Please provide a product description")
    @Size(min = 2, max = 5000, message = "Product description should be minimum 2 character and maximum 5000 character")
    private String details;

    @Min(value = 0, message = "Price should not be negative")
    private float price;

    @Size(min = 1, max = 10, message = "Product should have minimum 1 image and maximum 10 images")
    private Set<MultipartFile> images;
}

8
投票

我发现

@RequestBody
(也将类注释为
@RestController
)更适合 AJAX 请求,您可以完全控制发出的请求的内容,并且内容以 XML 或 JSON 形式发送(因为 Jackson) 。这允许内容轻松创建模型对象。

相反,

@ModelAttribute
似乎更适合forms,其中有一个支持表单的“命令”对象(不一定是模型对象)。


7
投票

如果您使用ModelAttribute注释,您可以直接在视图层中访问您的“宠物”对象。此外,您可以在控制器上的方法中实例化该对象以放置模型。 看到这个

ModelAttribute 让您有机会部分使用此对象,但使用 RequestBody,您可以获得请求的所有正文。


2
投票

我认为@ModelAttribute和@RequestBody都有相同的用途,只有区别 @ModelAttribute 用于普通 Spring MVC,@RequestBody 用于 REST Web 服务。它是@PathVariable 和@PathParam。但在这两种情况下我们都可以混合使用。我们可以在 REST 中使用 @PathVariable,反之亦然。


0
投票

使用 @ModelAttribute,您可以在 URL 参数中传递数据,而使用 @RequestBody,您可以将其作为 JSON 正文传递。如果您正在制作 REST API,那么最好使用 @RequestBody。在大多数 YouTube 教程中,您可能会发现 @ModelAttribute 的使用 - 这仅仅是因为它们可能正在演示有关 Spring MVC 的概念并使用 URL 来传递数据。


0
投票

我们需要以下 jsp 标签来将您的实体数据绑定到 jsp 表单字段:
表单来自spring标签库:
以下不是完整的html,但我希望你能自己联系一下:

<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>

        <form:form action="save" method="post" modelAttribute="patient">
            <table>
                <tr>
                    <td>Name</td>
                    <td>
                        <form:input path="patient.patient_name"  /> <br />
                        
                    </td>
                </tr>
                <tr>
                    <td>Phone</td>
                    <td>
                        <form:input path="patient.phone_number" /> <br />
                    </td>
                </tr>
                <tr>
                    <td colspan="2"><button type="submit">Submit</button></td>
                </tr>
            </table>
        </form:form>

表单必须处理两次,一次是在渲染表单之前,在此期间我们需要为属性值提供适当的 bean 实例化

modelAttribute="patient"

  1. 为此,控制器类(在类定义级别)您需要有
    @RequestMapping
    注释。
  2. 你需要有如下的handler方法参数
@GetMapping("logincreate")

public String handleLoginCreate(@ModelAttribute("login") Login login, Model model)
{
    System.out.println(" Inside handleLoginCreate  ");
    model.addAttribute("login",login);
    return "logincreate";
}

Spring 将扫描所有处理方法

@ModelAttribute
并使用 Login 类的默认构造函数实例化它,并调用其所有 getter 和 setter(对于从表单到“登录”的 jsp 绑定)。如果缺少以下任何一项,jsp将不会显示,会抛出各种异常

  1. 吸气剂/吸气剂
  2. 默认构造函数
  3. model.addAttribute("登录",登录);
  4. 类级别@RequestMapping
  5. 方法参数级别@ModelAttribute

另外,jsp中action的handler方法,如上面的形式

action="save"
,handler方法也可能是这样的:

@PostMapping("save")

public String saveLoginDetails(@ModelAttribute("login") Login login, Model model) {
    
    //write codee to insert record into DB
    System.out.println(" Inside save login details  ");
    System.out.println("The login object is " + login.toString());
    System.out.println("The model object contains the login attribute"+ model.getAttribute("login"));   
    loginService.saveLogin(login);
    return "welcome";
}

重要的学习是:

  1. 在启动表单之前,Spring应该有适当的注释来指示表单的后台bean,在上面的示例中,“后台bean”或“绑定对象”是使用适当的处理方法的参数注释登录登录
    @ModelAttribute("login") Login login

0
投票
当您想要包含多部分文件作为正文时,基本上会使用

@ModelAttribute。要从前端传递数据,您需要将数据转换为 JSON。甚至测试用例的编写也有点不同。您需要使用 contentType(MediaType.APPLICATION_FORM_URLENCODED) 作为内容类型,而不是 JSON 字符串,您需要将值传递为 .param("字段", 值)


0
投票

@RequestBody: 该注解用于将整个请求正文绑定到方法参数。它通常在请求负载为 JSON 或 XML 格式时使用。

@PostMapping("/example")
public ResponseEntity<String> handleRequest(@RequestBody ExampleDto exampleDto) {
   // Do something with the exampleDto object
   return ResponseEntity.ok("Request handled successfully");
}

@ModelAttribute: 该注解用于绑定请求参数(可以在查询字符串中,也可以在表单数据中) 方法参数或模型属性。它通常与 HTML 表单一起使用,或者当您想要从请求中提取单个参数时。

@PostMapping("/example")
public ResponseEntity<String> handleRequest(@ModelAttribute("name") String name, @ModelAttribute("age") int age) {
    // Do something with the name and age parameters
    return ResponseEntity.ok("Request handled successfully");
}
© www.soinside.com 2019 - 2024. All rights reserved.