Spring Boot: @ModelAttribute is null in controller method when using with multipart/form-data

445 Views Asked by At

I have a Spring Boot controller method that handles file uploads, and I'm trying to use the @ModelAttribute annotation to bind some fields from the request. Here's my controller method:

@PostMapping(value = "/{accountNo}/upload", consumes = "multipart/form-data")
public ResponseEntity<Object> uploadDocument(
        @PathVariable Long accountNo,
        @ModelAttribute RequestDTO requestDTO,
        @RequestParam("file") MultipartFile file,
        Authentication authentication) {
    // ...
}

The RequestDTO class contains fields that I want to bind from the request body/form data. However, I'm encountering an issue where the requestDTO object is always null in the method.

Due to the extensive length of certain attribute values, passing DTO data through request parameters is not feasible.

Is there something I'm missing in my setup, or are there any common pitfalls when using @ModelAttribute in this context? How can I ensure that the requestDTO object is correctly populated from the request?

I have verified that the request is being sent correctly, including the required fields for RequestDTO.

The @RequestBody annotation cannot be used in conjunction with multipart/form-data.

I used swagger to send data using JSON format.

{
     
      "accountNo": "211100001201",
      "kind": "hello",
      "name": "string",
      "url": "string",
      "location": "string",
      "storageStatus": "string",
      "actionType": "string",
      "value1": "string",
      "detail": "string"
    }

Thank you for your assistance!

2

There are 2 best solutions below

1
Karim Halayqa On

You can just add the dto without any annotation, spring will automatically bind the form data to the dto fields.

@PostMapping(value = "/{accountNo}/upload", consumes = "multipart/form-data")
public ResponseEntity<Object> uploadDocument(
        @PathVariable Long accountNo,
        RequestDTO requestDTO,
        @RequestParam("file") MultipartFile file,
        Authentication authentication) {
    // ...
}

http://dolszewski.com/spring/how-to-bind-requestparam-to-object/

this will allow you to enter the fields of the dto in form data and they will be mapped to the dto's fields.

0
Romario On

If you state that your endpoint consumes = "multipart/form-data" then it does not expect to get JSON from your request to populate your DTO.

Add file to your RequestDTO and send request in "multipart/form-data" but not in JSON. (Content-Type header should contain multipart/form-data value : Content-Type: multipart/form-data;)

Here is the link how to upload file from swagger-ui. The rest of parameters should be in line with file.