Spring: @ModelAttribute VS @RequestBody

Please correct me if I am wrong. Both can be used for Data Binding.

The question is when to use @ModelAttribute?

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

In addition, when to use @RequestBody?

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

According to my understanding both serves the similar purpose.

Thanks!!


Solution 1:

The simplest way for my understanding is, the @ModelAttribute will take a query string. so, all the data are being pass to the server through the url.

As for @RequestBody, all the data will be pass to the server through a full JSON body.

Solution 2:

@ModelAttribute is used for binding data from request param (in key value pairs),

but @RequestBody is used for binding data from whole body of the request like POST,PUT.. request types which contains other format like json, xml.

Solution 3:

If you want to do file upload, you have to use @ModelAttribute. With @RequestBody, it's not possible. Sample code

@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);
    }

}

ProductInput class

@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;
}