Search code examples
javaspringspring-bootrestspring-mvc

Spring controller that accepts both MultipartFile and also a JSON Object


I need to make a POST endpoint in Java Springboot that accepts a MultipartFile (a raw file like xlsx, doc that we can upload from windows explorer) and also a JSON Object (metadata). The JSON Object will be provided as a String, like:

{
  "address": "string",
  "fullName": "string"
}

I tried the following:

Controller:

@PostMapping(path = "/post", consumes = {"application/json","multipart/form-data"})
  public ResponseEntity<String> endpoint(
    @RequestBody ReportDto reportDto,
    @RequestPart("myFile") MultipartFile myFile
  ){
  return ResponseEntity.ok(service.process(reportDto,myFile));
  }
  

ReportDto used in controller:

 public class ReportDto{
  
  String address;
  String fullName;
    //getters
    //setters
    //all arg constructor
    //no arg constructor
  
  }

When I try to hit the endpoint through Swagger or through POSTMAN, i get HTTP 415 : Unsupported Media error.

My CURL request looks like this:

curl -X 'POST' \
  'http://localhost:8080/api/v1/dashboards/post' \
  -H 'accept: */*' \
  -H 'Authorization: Bearer somebearertoken' \
  -H 'Content-Type: multipart/form-data' \
  -F 'reportDto={
  "address": "string",
  "fullName": "string"
}' \
  -F 'myFile=@Table_New.xlsx;type=application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'

Please help me on resolving this


Solution

  • Modify the controller method like this:

    @PostMapping(path = "/post", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
    public ResponseEntity<String> endpoint(
            @RequestPart ReportDto reportDto,
            @RequestPart MultipartFile myFile) {
        return ResponseEntity.ok(service.process(reportDto, myFile));
    }
    

    Please note: the name attribute in the annotation RequestPart is not required if it matches the parameter name. Please also note that using the constants defined in MediaType helps avoid typo/mistakes.

    You should also add the media type definition for reportDto to your CURL/Postman request:

    -F 'reportDto={
        "address": "string",
        "fullName": "string"};
        type=application/json'