In the tutorial, we guide how to build a SpringBoot web-application to Upload/Download MultipartFile to FileSystem using Bootstrap 4 & JQuery Ajax.
Contents
Technologies
- Java 8
- Spring Tool Suite: Version 3.9.4.RELEASE
- Spring Boot: 2.0.2.RELEASE
- Bootstrap 4
- JQuery Ajax
Goal
We create a SpringBoot project as below:
-> Upload/Download Form:
Practice
We create a SpringBoot project with below dependencies:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> |
FrontEnd
Upload Multipart-Form
<!DOCTYPE html> <html lang="en"> <head> <title>Upload MultipartFile</title> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"></script> <script src="/js/postrequest.js"></script> <script src="/js/getrequest.js"></script> </head> <body> <div class="container h-100"> <div class="row h-100 justify-content-center align-items-center"> <div class="col-sm-5"> <h3>Upload MultipartFile to FileSystem</h3> <form method="POST" enctype="multipart/form-data" id="fileUploadForm"> <div class="form-group"> <label class="control-label" for="uploadfile">Upload File:</label> <input type="file" class="form-control" id="uploadfile" placeholder="Upload File" name="uploadfile"></input> </div> <button type="submit" class="btn btn-default" id="btnSubmit">Upload</button> <button type="button" class="btn btn-default" id="btnGetFiles">Files</button> </form> <hr/> <div id="listFiles"> </div> </div> </div> </div> </body> </html> |
Ajax Post/Get MultipartFile
– JQuery Ajax to Post MultipartFile is implemented in ‘\src\main\resources\static\js\postrequest.js’ file:
$(document).ready( () => { $("#btnSubmit").click((event) => { //stop submit the form, we will post it manually. event.preventDefault(); doAjax(); }); }); function doAjax() { // Get form var form = $('#fileUploadForm')[0]; var data = new FormData(form); $.ajax({ type: "POST", enctype: 'multipart/form-data', url: "/api/file/upload", data: data, processData: false, //prevent jQuery from automatically transforming the data into a query string contentType: false, cache: false, success: (data) => { $("#listFiles").text(data); }, error: (e) => { $("#listFiles").text(e.responseText); } }); } |
– JQuery Ajax to Retrieve/Download MultipartFile is implemented in ‘\src\main\resources\static\js\getrequest.js’ file:
$( document ).ready( () => { // GET REQUEST $("#btnGetFiles").click( (event) => { event.preventDefault(); ajaxGet(); }); // DO GET function ajaxGet(){ $.ajax({ type : "GET", dataType: "json", url : "/api/file/all", success: (data) => { //clear old data $("#listFiles").html(""); /* render list of files */ $("#listFiles").append('<ul>'); $.each(data, (index, fileUrl) => { var filename = fileUrl.split('\\').pop().split('/').pop(); $("#listFiles").append('<li><a href=' + fileUrl + '>' + filename + '</a></li>'); }); $("#listFiles").append('</ul>'); }, error : (err) => { $("#listFiles").html(err.responseText); } }); } }) |
BackEnd
File Storage
– Create interface FileStorage.java file:
package com.javasampleapproach.multipartfile.controller.filestorage; import java.nio.file.Path; import java.util.stream.Stream; import org.springframework.core.io.Resource; import org.springframework.web.multipart.MultipartFile; public interface FileStorage { public void store(MultipartFile file); public Resource loadFile(String filename); public void deleteAll(); public void init(); public Stream<Path> loadFiles(); } |
– Implement above interface by FileStorageImpl.java:
package com.javasampleapproach.multipartfile.controller.filestorage; import java.io.IOException; import java.net.MalformedURLException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.stream.Stream; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.io.Resource; import org.springframework.core.io.UrlResource; import org.springframework.stereotype.Service; import org.springframework.util.FileSystemUtils; import org.springframework.web.multipart.MultipartFile; @Service public class FileStorageImpl implements FileStorage{ Logger log = LoggerFactory.getLogger(this.getClass().getName()); private final Path rootLocation = Paths.get("filestorage"); @Override public void store(MultipartFile file){ try { Files.copy(file.getInputStream(), this.rootLocation.resolve(file.getOriginalFilename())); } catch (Exception e) { throw new RuntimeException("FAIL! -> message = " + e.getMessage()); } } @Override public Resource loadFile(String filename) { try { Path file = rootLocation.resolve(filename); Resource resource = new UrlResource(file.toUri()); if(resource.exists() || resource.isReadable()) { return resource; }else{ throw new RuntimeException("FAIL!"); } } catch (MalformedURLException e) { throw new RuntimeException("Error! -> message = " + e.getMessage()); } } @Override public void deleteAll() { FileSystemUtils.deleteRecursively(rootLocation.toFile()); } @Override public void init() { try { Files.createDirectory(rootLocation); } catch (IOException e) { throw new RuntimeException("Could not initialize storage!"); } } @Override public Stream<Path> loadFiles() { try { return Files.walk(this.rootLocation, 1) .filter(path -> !path.equals(this.rootLocation)) .map(this.rootLocation::relativize); } catch (IOException e) { throw new RuntimeException("\"Failed to read stored file"); } } } |
Index Controller
– Create IndexController.java to server uploadfile.html view:
<!DOCTYPE html> <html lang="en"> <head> <title>Upload MultipartFile</title> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"></script> <script src="/js/postrequest.js"></script> <script src="/js/getrequest.js"></script> </head> <body> <div class="container h-100"> <div class="row h-100 justify-content-center align-items-center"> <div class="col-sm-5"> <h3>Upload MultipartFile to FileSystem</h3> <form method="POST" enctype="multipart/form-data" id="fileUploadForm"> <div class="form-group"> <label class="control-label" for="uploadfile">Upload File:</label> <input type="file" class="form-control" id="uploadfile" placeholder="Upload File" name="uploadfile"></input> </div> <button type="submit" class="btn btn-default" id="btnSubmit">Upload</button> <button type="button" class="btn btn-default" id="btnGetFiles">Files</button> </form> <hr/> <div id="listFiles"> </div> </div> </div> </div> </body> </html> |
Upload/Download RestAPIs
– Implement upload-file RestAPI in UploadFileController.java file:
package com.javasampleapproach.multipartfile.controller.rest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import com.javasampleapproach.multipartfile.controller.filestorage.FileStorage; @RestController public class UploadFileController { @Autowired FileStorage fileStorage; /* * MultipartFile Upload */ @PostMapping("/api/file/upload") public String uploadMultipartFile(@RequestParam("uploadfile") MultipartFile file) { try { fileStorage.store(file); return "File uploaded successfully! -> filename = " + file.getOriginalFilename(); } catch (Exception e) { return "Error -> message = " + e.getMessage(); } } } |
– Implement download/retrieve files RestAPIs in DownloadFileController.java file:
package com.javasampleapproach.multipartfile.controller.rest; import java.util.List; import java.util.stream.Collectors; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.Resource; import org.springframework.http.HttpHeaders; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder; import com.javasampleapproach.multipartfile.controller.filestorage.FileStorage; @RestController public class DownloadFileController { @Autowired FileStorage fileStorage; /* * List All Files */ @GetMapping("/api/file/all") public List<String> getListFiles() { return fileStorage.loadFiles().map( path -> MvcUriComponentsBuilder.fromMethodName(DownloadFileController.class, "downloadFile", path.getFileName().toString()).build().toString()) .collect(Collectors.toList()); } /* * Download Files */ @GetMapping("/api/file/{filename}") public ResponseEntity<Resource> downloadFile(@PathVariable String filename) { Resource file = fileStorage.loadFile(filename); return ResponseEntity.ok() .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + file.getFilename() + "\"") .body(file); } } |
Run & Check Results
Run the SpringBoot project, then makes upload/download requests ->
Upload Files
-> Stored files:
Retrieve Files
-> Browser Network logs:
Download Files
-> Browser Network logs:
SourceCode
SpringBootUploadDownloadMultipartFile
Last updated on June 4, 2018.