MultipartFile uploads from a ReactJS UI to a Spring Boot service

Satyajit Patnaik
3 min readMay 26, 2020

--

In this article, I will tell about the implementation of file uploads using Multipart requests. Multipart requests combine one or more sets of data into a single body, separated by boundaries. For this purposes of this article, I am going to write UI in ReactJS and a service using Spring boot.

  • The UI will have the capability of choosing a file or multiple files and sending a multipart request using Fetch JavaScript API to the service.
  • Also, we will see the way we can combine some mandatory JSON request body wrapped inside a Multipart request along with the files.
  • The service will receive the multipart request and read the contents for this example. Use cases can be further developed where the file content can be used for further data processing which would not be covered in the scope of this article.

We will start step by step in building in this small use-case slash application.

  • First, we will build a ReactJS client UI application with a simple file upload feature.
  • Second, we will build the Spring Boot service to receive the files from the client.

ReactJS Client UI Application

Create a small ReactJS application using the create-react-app tool as below. On starting the application, the UI should load up on localhost:3000.

npx create-react-app reactjs-file-upload-ui
cd reactjs-file-upload-ui
npm start

Next we will write a simple ReactJS component which renders a file input field for multiple files. You will see a lot of styling classes like uk-margin-medium-top, these are from ui-kit component styling library.

import React, { Component } from 'react';
import axios from 'axios';
class FileUploadComponent extends Component { uploadJSONFiles(event) {
event.preventDefault();
let formData = new FormData();
let jsonBodyData = { 'someKey': 'someValue' };
for(let key of Object.keys(event.target.files)) {
if (key !== 'length') {
formData.append('files', event.target.files[key]);
}
}
formData.append('jsonBodyData',
new Blob([JSON.stringify(jsonBodyData)], {
type: 'application/json'
}));
fetch('/api/service/uploadfiles', {
method: 'POST',
body: formData
}).then(response => response.json())
.then(result => console.log('Files successfully uploaded!'))
.catch(error => console.log('error occurred!'));
}
render() {
<div className="uk-margin-medium-top">
<label>Upload Files</label>
<input type="file"
onChange={(event) => this.uploadJSONFiles(event)}
multiple/>
</div>
}
}
export default FileUploadComponent;

Above in the ReactJS component, when a HTTP fetch call is made, the request is of Multipart type. The browser helps in filling the method type as multipart/form-data automatically. Now we will implement the service side using Spring Boot which consumes this client request and logs details of the multipart object.

Spring Boot Service Application to consume multipart requests

In the service side, we will implement the consumption of the multipart requests. The special part in these requests is that it holds two kinds of data wrapped in a FormData object whose http content-type is multipart/form-data. Below is the code implementation in a Controller. Further use cases can be developed which could use the files from here to do any special processing or data persistence.

@RestController
@CrossOrigin
@SuppressWarnings({ "unchecked", "rawtypes" })
@RequestMapping(value = "/api/service")
public class FileUploadController {
@ApiOperation(value = "Upload of multiple files",
response = Iterable.class)
@ApiResponses(value = {
@ApiResponse(code = 200,
message = "Successfully uploaded multiple files"),
@ApiResponse(code = 404, message = "Not found.")
})
@RequestMapping(value="/uploadfiles",
method=RequestMethod.POST,
produces=MediaType.APPLICATION_JSON_VALUE,
consumes=MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity uploadFiles(
@RequestPart("jsonBodyData") SomeModel dataReqData,
@RequestPart("files") MultipartFile[] files) throws IOException{
JSONObject response = new JSONObject();
LOGGER.info("JSON Request Body Data: {}", dataReqData);
for(MultipartFile file : files) {
LOGGER.info(file.getOriginalFilename());
}
return new ResponseEntity<>(response, HttpStatus.OK);
}
}

Note: To keep the code shorter for the article purposes, the logger instantiation and the imports have not included in the code snippet.

Some helpful links which helped me during my use case implementation -

The above implementation is the simple way that I could use recently to upload multiple files to a service using Multipart requests. I hope it helps fellow coders who might be dealing with features using multipart uploads. Happy Coding!

--

--