Open In App

Spring MVC – Multiple File Upload with Progress Bar in Ajax and JQuery

Last Updated : 05 Jan, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

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 application. In this article, we will discuss the Multiple File Uploading process by using Spring MVC with the help of Ajax and JQuery to display the progress bar while uploading the files into one folder. If all files are uploaded the progress bar shows 100% completion on the HTML page. ( Spring MVC Reference )

Prerequisites

  • Spring Boot Framework with MVC Pattern
  • Thymeleaf
  • Ajax
  • JQuery
  • Bootstrap
  • One Folder for saving uploaded files.
  • Project Category is Gradle

The Spring Boot with MVC Pattern is used for triggering the Front-End Logic. For this, we have used Thymeleaf, which works as a bridge between Front-End and Back-End. Any update in the Back end then the Thymeleaf can Trigger the HTML content based upon the back-end functionality. Ajax and JQuery are used for providing Dynamic Behavior of the HTML page and Bootstrap is used for Creating Web Page with Responsive Behavior. After that create one folder in your system for saving the uploaded files.

Steps by Step Implementation for Multiple File Upload

  • Create a Spring Stater Project using Spring Tool Suite. (Create a Spring Boot Project)
  • While Creating the Project Select the required Dependencies (mentioned below) for this Application.
  • After completion of the project creation In the Main Project Package create one Controller class for Handling the Multiple File Upload process
  • After That create one HTML File in the Templates which is located in the Resources folder in the main project file and develop the Front-End code using HTML, Bootstrap is used for creating the Template, and Ajax and JQuery are used for providing the Dynamic Behavior for Progress Bar.
  • Once completed both Front-End and Back-End Development Then run this project as Run a Spring Boot App. Then open localhost with the default port number in Browser.

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'
}

Project Folder Structure

Project Structure

Now we will start the development process of Back-End Using Spring Boot with MVC Pattern and Thymeleaf for triggering the back-end result on the HTML page.

application.properties File (set application configuration):

# thymeleaf configuration
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
# Maximum file size
spring.servlet.multipart.max-file-size=5MB
# Maximum request size
spring.servlet.multipart.max-request-size=5MB

In above configuration file, we have written Application configuration for Thymeleaf and Maximum and Minimum size of the File in the format of MB’s.

Controller Layer

Now we will create back-end logic for handling multiple files uploading process after that save those files into one folder or specific location. This code is developed under controller layer.

FileUploadController.java:

Java




package com.gfg.articles;
  
import java.io.File;
import java.io.IOException;
  
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
  
@Controller
public class FileUploadController {
  
    private static final String UPLOAD_DIR = "./src/upload/";
  
    @RequestMapping("/")
    public String index() {
        return "index";
    }
      
    @PostMapping("/upload")
    @ResponseBody
    public ResponseEntity<String> handleFileUpload(@RequestParam("files") MultipartFile[] files) {
        if (files == null || files.length == 0) {
            return ResponseEntity.badRequest().body("No files selected for upload.");
        }
  
        try {
            for (MultipartFile file : files) {
                // Get the file name
                String fileName = file.getOriginalFilename();
  
                // Create the directory if it doesn't exist
                File directory = new File(UPLOAD_DIR);
                if (!directory.exists()) {
                    directory.mkdirs();
                }
  
                // Save the file to the server
                File serverFile = new File(directory.getAbsolutePath() + File.separator + fileName);
                file.transferTo(serverFile);
            }
  
            return ResponseEntity.ok("Files uploaded successfully!");
        } catch (IOException e) {
            e.printStackTrace();
            return ResponseEntity.status(500).body("Error uploading files: " + e.getMessage());
        }
    }
}


In the above code we have created different types of end points for different operations like display the html file, uploading files and others. Now we will discuss each end point.

  • @RequestMapping(“/”) this end point is used for displaying the HTML page by using Thymeleaf.
  • @PostMapping(“/upload”) this end point is used for uploading the files into given location.
  • In the above code I take One location for saving uploaded files.

Here MultiPartFile is used for dealing with files from front-end to back-end if file is null or file length equals to 0 then we will throw one error that is no files selected for upload. And this message triggered on HTML page through Thymeleaf. Otherwise, files are successfully uploaded into given location.

View Layer

Normally HTML, JSP and other files comes under view layer. In this Application I used HTML pages for displaying user interface. Now we will see the Front-End Code with Its functionality.

Index.html

HTML




<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>File Upload with Progress Bar</title>
    <link rel="shortcut icon" href="https://cdn-icons-png.flaticon.com/512/338/338864.png">
    <script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
</head>
<body class="bg-light">
  
<div class="container mt-5 p-5">
    <h4 class="mb-4 text-success" style="font-weight: 700; font-family: 
    'Times New Roman', Times, serif;">Spring MVC - Multiple File Upload with Progress Bar in Ajax and JQuery</h4>
  
    <form id="uploadForm" class="form-control p-5 mt-5">
        <div class="mb-3">
            <label for="fileInput" class="form-label" style="font-weight: 600;">Select Files</label>
            <input type="file" class="form-control" id="fileInput" multiple>
        </div>
        <button type="button" class="btn btn-success mt-2" onclick="uploadFiles()">Upload</button>
    </form>
  
    <div id="progressBarContainer" class="mt-4" style="display: none;">
        <div class="progress">
            <div id="progressBar" class="progress-bar bg-success" role="progressbar" 
                 style="width: 100%;">100%</div>
        </div>
    </div>
</div>
  
<script th:inline="javascript">
    /*<![CDATA[*/
    var uploadUrl = /*[[@{/upload}]]*/ '/upload'; // Use Thymeleaf to generate the URL
  
    function uploadFiles() {
        var files = $('#fileInput')[0].files;
  
        if (files.length === 0) {
            alert("Please select at least one file.");
            return;
        }
  
        var formData = new FormData();
        for (var i = 0; i < files.length; i++) {
            formData.append('files', files[i]);
        }
  
        $.ajax({
            url: uploadUrl,
            type: 'POST',
            data: formData,
            contentType: false,
            processData: false,
            xhr: function () {
                var xhr = new XMLHttpRequest();
                xhr.upload.onprogress = function (e) {
                    if (e.lengthComputable) {
                        var percentage = (e.loaded / e.total) * 100;
                        $('#progressBar').width(percentage + '%').html(percentage.toFixed(2) + '%');
                    }
                };
                return xhr;
            },
            success: function (response) {
                alert(response);
                $('#progressBarContainer').hide();
            },
            error: function (error) {
                alert('Error uploading files: ' + error.responseText);
            }
        });
  
        $('#progressBarContainer').show();
    }
    /*]]>*/
</script>
  
</body>
</html>


In the above code we have used HTML, Ajax and JQuery for providing dynamic behavior while uploading the files into server through this Application. In this HTML code we have created one form which is used for selecting files from computer.

Form:

HTML




<form id="uploadForm" class="form-control p-5 mt-5">
        <div class="mb-3">
            <label for="fileInput" class="form-label" style="font-weight: 600;">Select Files</label>
            <input type="file" class="form-control" id="fileInput" multiple>
        </div>
        <button type="button" class="btn btn-success mt-2" onclick="uploadFiles()">Upload</button>
    </form>


This piece code is handling selection files from computer. For selecting files from computer we use one html element that is input with type file. This attribute triggers file selection process. After that we have created one Progress bar.

Progress Bar:

HTML




<div id="progressBarContainer" class="mt-4" style="display: none;">
        <div class="progress">
            <div id="progressBar" class="progress-bar bg-success" 
                 role="progressbar" style="width: 100%;">100%</div>
        </div>
    </div>


Initially this progress bar hidden. While uploading the files this comes into picture. It is possible by using display: none. By using Bootstrap, we have created one progress with width equals 100%.

Script:

Javascript




<script th:inline="javascript">
    /*<![CDATA[*/
    var uploadUrl = /*[[@{/upload}]]*/ '/upload'; // Use Thymeleaf to generate the URL
  
    function uploadFiles() {
        var files = $('#fileInput')[0].files;
  
        if (files.length === 0) {
            alert("Please select at least one file.");
            return;
        }
  
        var formData = new FormData();
        for (var i = 0; i < files.length; i++) {
            formData.append('files', files[i]);
        }
  
        $.ajax({
            url: uploadUrl,
            type: 'POST',
            data: formData,
            contentType: false,
            processData: false,
            xhr: function () {
                var xhr = new XMLHttpRequest();
                xhr.upload.onprogress = function (e) {
                    if (e.lengthComputable) {
                        var percentage = (e.loaded / e.total) * 100;
                        $('#progressBar').width(percentage + '%').html(percentage.toFixed(2) + '%');
                    }
                };
                return xhr;
            },
            success: function (response) {
                alert(response);
                $('#progressBarContainer').hide();
            },
            error: function (error) {
                alert('Error uploading files: ' + error.responseText);
            }
        });
  
        $('#progressBarContainer').show();
    }
    /*]]>*/
</script>


The above code enable dynamic behavior of HTML page while uploading the files. If any errors are raised the alert is enabled by this script. If successfully uploaded then the progress bar is enabled by this script code.

Output:

1. Before Uploading Multiple Files Through Application (Index page):

Index Page

2. Folder location for uploading files:

Folder location for Uploading Files

3. While No files selected:

No Files Selected

4. After Uploading Multiple Files Through Application:

Files Selected to Uploaded

5. Window while uploading files:

 Interface While Uploading Files

6. Directory After file upload:

Project Structure After Upload

Conclusion

While sharing information with others or send any application to jobs, This Multiple File Uploading concept plays an important role in the that situation. In this tutorial I develop this Multiple File Upload application using Spring Boot with MVC pattern. For this Application first we create one html form for selecting files after that we write script for handling progress bar while uploading files. After that We build back-end logic for uploading files into given location.



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads