In this tutorial we will learn how to manage the upload and download of files using Spring Boot REST Services. We will use for this purpose Swagger UI to interact with a REST Controller.
Setting up your Spring Boot project
In order to get started with this tutorial we suggest reading this Intro to REST Services and Swagger UI so that you can bootstrap your project quickly:
Firstly, add a Spring Boot application class to bootstrap your project:
@SpringBootApplication public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }
Next, we will code our main Controller Class which will handle the upload and download of files:
@RestController public class RestFilesController { private final Logger logger = LoggerFactory.getLogger(RestFilesController.class); // Save the uploaded file to this folder private static String UPLOADED_FOLDER = "/tmp/uploads/"; // Single File upload @PostMapping(value = "/rest/upload", consumes = { "multipart/form-data" }) @Operation(summary = "Upload a single File") public ResponseEntity < ? > uploadFile(@RequestParam("file") MultipartFile uploadfile) { logger.debug("Single file upload!"); if (uploadfile.isEmpty()) { return new ResponseEntity("You must select a file!", HttpStatus.OK); } try { saveUploadedFiles(Arrays.asList(uploadfile)); } catch (IOException e) { return new ResponseEntity < > (HttpStatus.BAD_REQUEST); } return new ResponseEntity("Successfully uploaded - " + uploadfile.getOriginalFilename(), new HttpHeaders(), HttpStatus.OK); } // Multiple File upload @PostMapping(value = "/rest/multipleupload", consumes = { "multipart/form-data" }) @Operation(summary = "Upload multiple Files") public ResponseEntity uploadFiles(@RequestPart String metaData, @RequestPart(required = true) MultipartFile[] uploadfiles) { String uploadedFileName = Arrays.stream(uploadfiles).map(x -> x.getOriginalFilename()).filter(x -> !StringUtils.isEmpty(x)).collect(Collectors.joining(" , ")); if (StringUtils.isEmpty(uploadedFileName)) { return new ResponseEntity("please select a file!", HttpStatus.OK); } try { saveUploadedFiles(Arrays.asList(uploadfiles)); } catch (IOException e) { return new ResponseEntity < > (HttpStatus.BAD_REQUEST); } return new ResponseEntity("Successfully uploaded - " + uploadedFileName, HttpStatus.OK); } // Single File download @RequestMapping(path = "/rest/download", method = RequestMethod.GET) @Operation(summary = "Download a File") public ResponseEntity < Resource > downloadFile(String fileName) throws IOException { File file = new File(UPLOADED_FOLDER + fileName); HttpHeaders headers = new HttpHeaders(); headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + fileName); headers.add("Cache-Control", "no-cache, no-store, must-revalidate"); headers.add("Pragma", "no-cache"); headers.add("Expires", "0"); Path path = Paths.get(UPLOADED_FOLDER + fileName); ByteArrayResource resource = new ByteArrayResource(Files.readAllBytes(path)); return ResponseEntity.ok() .headers(headers) .contentLength(file.length()) .contentType(MediaType.APPLICATION_OCTET_STREAM) .body(resource); } // save file private void saveUploadedFiles(List < MultipartFile > files) throws IOException { File folder = new File(UPLOADED_FOLDER); if (!folder.exists()) { folder.mkdir(); } for (MultipartFile file: files) { if (file.isEmpty()) { continue; // next pls } byte[] bytes = file.getBytes(); Path path = Paths.get(UPLOADED_FOLDER + file.getOriginalFilename()); Files.write(path, bytes); } } }
Our Controller class includes three main methods:
- uploadFile: which handles the upload of a single File
- uploadFiles: which handles the upload of a multiple Files
- downloadFile: that you can use to download a File
All files are uploaded in the UPLOADED_FOLDER path.
Next, to build your project, make sure you have the starter-web and springdoc-openapi-ui dependencies in place:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-ui</artifactId> <version>1.6.6</version> </dependency>
We will use the latter dependency to test our Rest Controller with Swagger UI.
Testing the Rest Controller
Next, build and run the application
mvn install spring-boot:run
Finally, reach out Swagger’s UI at http://localhost:8080/swagger-ui/index.html where you can test the application:
Next, select the method you want to test and “try out”. For example, let’s test file Uploading:
Pick up the file you want to upload and click on “Execute”. To verify that the file is available, check the upload path to see if the file is there:
$ ls /tmp/uploads/ swagger1.png
Finally, test File Download using the appropriate REST HTTP GET:
Click on Execute and verify that Download starts on your browser. Great! you just managed to Upload / Download files with Spring Boot!
Source code for this tutorial: https://github.com/fmarchioni/masterspringboot/tree/master/rest/upload-download
Jakarta or Java EE User ? Then check this tutorial to learn how to upload and download files with JAX-RS.