Spring MVC – Implementing File Uploads and Downloads
Last Updated :
06 Sep, 2024
Spring MVC is a widely used framework for developing robust web applications in Java. It simplifies handling HTTP requests and responses, including file uploads and downloads. File uploads enable users to send files to the server, while file downloads allow users to retrieve files from the server. This article explains how to create a user interface for uploading and downloading files with related examples and outputs for you to take a look at.
Application Features
Below are the features provided in this application:
- Responsive Web Application: Utilizes the Bootstrap framework for a responsive design.
- Upload Files: Enables users to upload files to a designated storage location.
- Display Files: Shows uploaded files in a table format with filenames and download buttons.
- Download Files: Allows users to download files individually by clicking a download button.
- Basic Error Handling: Prevents uploading of empty files.
Prerequisites
To understand this article you have basic knowledge in the below listed topics.
Implementing File Uploads and Downloads using Spring MVC
Here's a step-by-step guide to creating a Spring Boot application that handles file uploads and downloads with a responsive web application design.
Step 1: Spring Application Creation
Create a Spring Boot application using Spring Initializr with the required dependencies.
To know, how to create a Spring Boot project, read this article: How to Create a Spring Boot Project?
Dependencies:
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
Project Folder Structure:
After successfully creating the project, the folder structure will look like the below image:
application.properties:
Open the application.properties, and add below properties.
spring.application.name=filestorage
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=10MB
Step 2: Create HTML File
Create an HTML file in the src/main/resources/templates
folder and integrate the Bootstrap framework:
index.html:
HTML
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>File Upload and Download</title>
</head>
<style>
form {
max-width: 900px;
height: auto;
border: 2px solid green !important;
}
</style>
<body>
<div class="files bg-success">
<div class="container">
<h3 class="text text-light p-3 text-center">Files Upload and Download</h3>
</div>
</div>
<div class="formdata mt-5 d-flex justify-content-center">
<div class="container">
<div class="row justify-content-center">
<form action="/upload" method="post" enctype="multipart/form-data" class="form-control p-4">
<div class="mb-3">
<label for="file" class="p-1" style="font-weight: bolder;">
<i class="fa fa-file-text"></i> Select File
</label>
<input type="file" name="file" id="file" class="form-control mt-3" required>
<button type="submit" class="btn btn-success form-control mt-4 text-light"
style="font-weight: bolder;">
<i class="fa fa-cloud-upload"></i> Upload File
</button>
</div>
</form>
</div>
<div class="tabledata mt-5">
<div class="table-responsive">
<table class="table table-bordered">
<thead class="bg-success text-light table-bordered">
<tr>
<th>File</th>
<th>Download</th>
</tr>
</thead>
<tbody class="text text-center">
<tr th:each="file : ${files}">
<td th:text="${file}"></td>
<td>
<a th:href="@{'/download/' + ${file}}" class="btn btn-success" style="border-radius: 100%; height: 40px; width: 40px;">
<i class="fa fa-cloud-download"></i>
</a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</body>
</html>
Output:
Step 3: Create Service File
Create a service class to handle file operations. We have created the service class by using @Service in the main package in the project folder. In this class we have created different methods.
- saveFile() : This method is used for save the uploaded file in the mentioned location.
- loadFile() : This method is used for load the all the files from the storage folder.
- getAllFiles() : This method is used for retrieve all files from the storage folder for displaying purpose.
FileService.java:
Java
package com.app;
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.nio.file.StandardCopyOption;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
@Service
public class FileService {
private final Path fileStorageLocation;
public FileService() {
this.fileStorageLocation = Paths.get("uploads").toAbsolutePath().normalize();
try {
Files.createDirectories(this.fileStorageLocation);
} catch (Exception ex) {
throw new RuntimeException("Could not create the directory where the uploaded files will be stored.", ex);
}
}
/**
* Saves the uploaded file to the specified location.
* @param file MultipartFile to be saved
*/
public void saveFile(MultipartFile file) {
String fileName = StringUtils.cleanPath(file.getOriginalFilename());
try {
Path targetLocation = this.fileStorageLocation.resolve(fileName);
Files.copy(file.getInputStream(), targetLocation, StandardCopyOption.REPLACE_EXISTING);
} catch (IOException ex) {
throw new RuntimeException("Could not store file " + fileName + ". Please try again!", ex);
}
}
/**
* Loads a file as a Resource for downloading.
* @param fileName the name of the file to be loaded
* @return Resource representing the file
*/
public Resource loadFile(String fileName) {
try {
Path filePath = this.fileStorageLocation.resolve(fileName).normalize();
Resource resource = new UrlResource(filePath.toUri());
if (resource.exists()) {
return resource;
} else {
throw new RuntimeException("File not found " + fileName);
}
} catch (MalformedURLException ex) {
throw new RuntimeException("File not found " + fileName, ex);
}
}
/**
* Retrieves all file names from the storage location.
* @return List of file names
*/
public List<String> getAllFiles() {
try {
return Files.walk(this.fileStorageLocation, 1)
.filter(path -> !path.equals(this.fileStorageLocation))
.map(this.fileStorageLocation::relativize)
.map(Path::toString)
.collect(Collectors.toList());
} catch (IOException ex) {
throw new RuntimeException("Could not list the files!", ex);
}
}
}
Step 4: Create File Controller
Create a controller class to handle HTTP requests. We have created a controller class by using @Controller annotation.
- getIndex() : This is one of the method created. This method is used for displaying the index.html file with GET mapping.
- uploadFile() : This method is used for uploading the files which is the POST mapping.
- downloadFile() : This method is used for download the files from the storage folder which is GET mapping.
FileController.java:
Java
package com.app;
import java.util.List;
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.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
@Controller
public class FileController {
@Autowired
private FileService fileService;
/**
* Displays the index page with a list of uploaded files.
* @param model the model to pass data to the view
* @return the name of the HTML template to be rendered
*/
@GetMapping("/")
public String getIndex(Model model) {
List<String> fileNames = fileService.getAllFiles();
model.addAttribute("files", fileNames);
return "index";
}
/**
* Handles file upload requests.
* @param file the file to be uploaded
* @param model the model to pass data to the view
* @return the redirect URL to the index page
*/
@PostMapping("/upload")
public String uploadFile(@RequestParam("file") MultipartFile file, Model model) {
fileService.saveFile(file);
model.addAttribute("message", "File uploaded successfully!");
return "redirect:/";
}
/**
* Handles file download requests.
* @param fileName the name of the file to be downloaded
* @return the ResponseEntity containing the file resource
*/
@GetMapping("/download/{fileName:.+}")
public ResponseEntity<Resource> downloadFile(@PathVariable String fileName) {
Resource resource = fileService.loadFile(fileName);
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getFilename() + "\"")
.body(resource);
}
}
Step 5: Run the Application
Once Business logic is develop for uploading and downloading files from the storage location. Run this application as Spring Boot App. And by default this application runs on port number 8080.
Step 6: Output
Access the application at http://localhost:8080
in your web browser.
http://localhost:8080/
Output:
output
Output Video:
Below is the entire output video:
Conclusion
This article demonstrated how to implement file upload and download functionality in a Spring Boot application. By following the provided code examples, you can easily create a file management system that allows users to upload and download files, all within a responsive web application interface.
Similar Reads
How to implement file uploading and downloading with Express ?
File uploading and downloading are important features of a web app. Here we are going to handle file upload using express-fileupload npm package, and the download is handled using res.download() function of the express. The express-fileupload is passed to the app as the middleware.Approach: First, i
3 min read
Spring MVC File Upload
Spring MVC provides a robust mechanism for handling file uploads in web applications. Using Spring MVC file upload, developers can easily integrate multipart file handling with the CommonsMultipartResolver. This article covers how to upload files in Spring MVC, configure MultipartResolver, and manag
6 min read
Spring MVC - Download File Controller
The Spring MVC is an approach for designing and developing the web application in the MVC pattern. In this article, we will learn how to develop logic for downloading a file from the server or file location in the Spring Boot with Spring Controller. For the application, we have used one HTML page, S
4 min read
Spring MVC â Implementing Asynchronous Request Processing
In Spring MVC, asynchronous request processing allows the server to handle requests in a non-blocking manner. This approach improves performance by freeing up resources while waiting for responses, which is especially useful for long-running tasks such as remote service calls, file processing, or da
8 min read
Spring MVC - Multiple File Upload with Progress Bar in Ajax and JQuery
File Uploading process plays an important role in data collection, Information sharing, and other situations. The File Uploading process is done in two instances. Those are the single file upload process and the other one uploading multiple files at a time. It depends upon the logic of the applicati
7 min read
How to implement a simple file upload with multipart form in Angular ?
In this article, we will see how to implement a simple file upload functionality in an Angular application. File uploading is a most common and significant functionality of any web application, to get the data in terms of files from the user or client to the server. We will see how to implement the
7 min read
Returning an Image or a File with Spring
In web development, it is common for servers to send various types of content to clients, including static and dynamic data, images, and files. The Spring Framework provides powerful tools to handle these requirements efficiently, allowing developers to return images and files directly from endpoint
3 min read
Two-Way Data Binding in Spring MVC with Example
Data Binding, as the name itself, is a self-explanatory word. In data binding what we have to do is we have to capture or store the data so that we can bind that data with another resource (for example displaying the data in the frontend part) as per our needs or we can also read the data from a var
7 min read
Difference Between Struts and Spring MVC
When developing Java-based web applications, choosing between Struts and Spring MVC is crucial for ensuring scalability and maintainability. Both frameworks follow the Model-View-Controller (MVC) architecture, but they differ in their approach and flexibility. Struts, an older and once-dominant fram
5 min read
Implementing Secure API Communication in Spring Boot
In modern web applications, securing API communication is important to protect sensitive data and ensuring the integrity of interactions between clients and servers. In this article, we will learn how to implement secure API communication in a Spring Boot application. Securing API communication is c
5 min read