Search code examples
javareactjsfileuploadfield

How do I send additional form fields along with a file upload using the FormData object to a Java API using React fetch?


My api is not detecting any of the RequestParams. However it works fine with Postman, just not when being called from React. I've also verified that the formData is being loaded correctly via console.log statements:

formData = file,[object File],uploadId,173,uploadTypeId,1,dateEntered,1625025600000,description,Fourth Addendum testing,enteredBy,769

Does the formData object need to be stringified or something?

Can someone tell me what I'm doing wrong? I'm getting the following error:

Required request parameter 'uploadId' for method parameter type Long is not present

Here is my React snippet:

let formData = new FormData();
formData.append("file", file);

formData.append("uploadId",uploadId);
formData.append("uploadTypeId",uploadTypeId);
formData.append("dateEntered",dateEntered);
formData.append("description",description);
formData.append("enteredBy",enteredBy);

let myHeaders = new Headers();
myHeaders.append("Content-Type", "multipart/form-data; boundary=XXX");
myHeaders.append("type", "formData");
const serverName = "http://localhost:8080/MyApp/api/uploads/update/;
myHeaders.append("Access-Control-Allow-Credentials", 'true');
myHeaders.append("Access-Control-Allow-Origin", '*');

const jwt = sessionStorage.getItem("jwt");
//console.log("fetch jwt = ", jwt) ;
let headerJwt = "Bearer " + jwt;
if (jwt != null) {
    myHeaders.append("Authorization", headerJwt);
}


//console.log("headers = ", Object.fromEntries(myHeaders));

let myInit = {method: "PUT"
            ,headers: myHeaders
};

let url = serverName + endpoint;

//console.log("data = " + data);

if (data)
    myInit.body = data;

let returnFetch = fetch(url, myInit);

Here is my Java api snippet:

@PutMapping(value = "/update", produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<Upload> update(
        @RequestParam("uploadId") Long uploadId,
        @RequestParam("uploadTypeId") Long uploadTypeId,
        @RequestParam("dateEntered") Date dateEntered,
        @RequestParam("description") String description,
        @RequestParam("enteredBy") Long enteredBy,
        @RequestPart(value = "file") MultipartFile file)
        throws JsonParseException, JsonMappingException, IOException
                ,SerialException, SQLException, DataAccessException
{
    Upload upload = new Upload();
    upload.setUploadId(uploadId);
    upload.setUploadTypeId(uploadTypeId);
    upload.setDateEntered(dateEntered);
    upload.setDescription(description);
    upload.setEnteredBy(enteredBy);
    
    MultipartFile multipartFile = file;
    
    byte[] bytes = multipartFile.getBytes();
    SerialBlob blob = new SerialBlob(bytes);
    upload.setFileBlob(blob);

    String filename = multipartFile.getOriginalFilename();
    upload.setFilename(filename);



    long recordsUpdated = this.myService.updateUpload(upload);
    
    return new ResponseEntity<Upload>(upload, HttpStatus.OK);
}

Solution

  • I found the problem!

    I had to do 2 things:

    1. Omit the content-type header.
    2. Stringify all the additional parameters.

    It works now!