Multiple file upload in Java with Progress bar – Ajax

Nowadays most web applications use file upload with progress bar user interface(UI). This article will help you to understand how it can be done through pure Javascript Ajax. Here we will discuss more developing the progress bar that is the front-end UI part. And in the server-side, we are using Java Servlet to handle it. If you are interested to learn more about the server-side implementation you can visit our Article File Upload in Java Servlet Example.

Multiple file upload in Java with Progress bar - Ajax

How to upload multiple files with a progress bar?

Here we will use HTML, Javascript, and Java Serverlet to create a file upload progress bar example application. Follow the below steps:

  1. Create the HTML document page to browse the files.
  2. Write the Javascript logic for upload and create a progress bar.
  3. Write the server-side logic in Servlet to handle the upload request.

Javascript Ajax Progress Bar Implementation

Let’s understand the implementation with sample points by referring to the below sample example-

  1. In the below example we are taking some global variables(totalFileSize, totalUploadedSize, totalFileCount, fileUploadedCount) to store specific data.
  2. When the user will click on the Upload button, the function startUploading() will be called. This is the initiation function of file upload. Here we are initializing the defined global variables.
  3. Here we are using XMLHttpRequest a Javascript class object to do the Ajax call. You can see in the function uploadFile().
  4. FormData a class object is used to attach the multipart file using append() method in order to upload it.
  5. progress, load, and error are the event which is fired when file upload will be happening. So we are going to bind these events with function onUploadProgress(), onUploadComplete(), and onUploadError() respectively.
  6. The function onUploadProgress() will be continuously called and updated in the progress bar. Here e.loaded will tell how many bytes have been uploaded to the server, so based on that we are calculating the percentage of the progress bar.
  7. The function onUploadComplete() will be called when a file gets uploaded completely to the server. Here we are doing the next ajax call if more files are yet to be uploaded otherwise updating 100% for the progress bar.
  8. The function onUploadError() will be called when an error occurs while uploading the files.

Javascript file upload progress bar ajax example

We are going to create an eclipse maven application. In this application the following files are required to create:

  • filesupload.html
  • FileUploadServlet.java
  • pom.xml

Multiple file upload maven application in Eclipse

file upload example in java - eclipse project structure

filesupload.html

<!DOCTYPE PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head><title>JavaCodePoint</title></head>
<body>
	<div style="border:1px solid #9a9a9a;padding:0px 20px 40px;width:50%;">
		<h2>Simple File Upload With Progress Bar</h2><hr>
		<div style="margin-bottom: 20px">
			<input type="file" id="files" multiple style="margin-bottom: 20px" /><br />
			<input type="button" value="Upload" onclick="startUploading()"/>
		</div>
		<div id='progress-bar-container' style='height: 20px;border: 1px solid #9a9a9a;'>
			<div id='progress-bar' style='height: 100%; background: #197d19; width: 0%'></div>
		</div>
		<div id="uploding-file"></div>
	</div>
</body>
<script>
	/* Globle variables */
	var totalFileSize, totalUploadedSize, totalFileCount, fileUploadedCount;
	
	/* start uploading files */
	function startUploading() {
		var files=document.getElementById('files').files;
		totalFileCount = files.length;
		totalUploadedSize = 0;
		fileUploadedCount = 0;
		totalFileSize = 0;		
		for (var i = 0; i < totalFileCount; i++) {
			totalFileSize += files[i].size;
		}
		// upload through ajax call
		uploadFile();
	}
	
	/* one by one file will be uploaded to the server by ajax call*/
	function uploadFile() {
		var file = document.getElementById('files').files[fileUploadedCount];
		var xhr = new XMLHttpRequest();
		var fd = new FormData();		
		fd.append("multipartFile", file);
		xhr.upload.addEventListener("progress", onUploadProgress, false);
		xhr.addEventListener("load", onUploadComplete, false);
		xhr.addEventListener("error", onUploadError, false);
		xhr.open("POST", "UploadServlet");
		xhr.send(fd);
		// update which file is uploading
		document.getElementById('uploding-file').innerHTML="Uploading "+file.name;
	}
	
	/* This function will continueously update the progress bar */
	function onUploadProgress(e) {
		if (e.lengthComputable) {
			var percentComplete = parseInt((e.loaded + totalUploadedSize) * 100	/ totalFileSize);
			var bar = document.getElementById('progress-bar');
			bar.style.width = percentComplete + '%';
			bar.innerHTML = percentComplete + ' % complete';
		} else {
			alert('unable to compute');
		}
	}
	
	/* This function will call when upload is completed */
	function onUploadComplete(e) {
		totalUploadedSize += document.getElementById('files').files[fileUploadedCount].size;
		fileUploadedCount++;
		if (fileUploadedCount < totalFileCount) {
			//ajax call if more files are there 
			uploadFile();
		} else {
			var bar = document.getElementById('progress-bar');
			bar.style.width = '100%';
			bar.innerHTML = '100% complete';
			document.getElementById('uploding-file').innerHTML="";
		}
	}

	/* This function will call when an error come while uploading */
	function onUploadError(e) {
		alert("Something went wrong!");
	}
</script>
</html>

FileUploadServlet.java

package com.javacodepoint.fileupload;

import java.io.File;
import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
/**
 * 
 * @author javacodepoint
 *
 */
@WebServlet("/UploadServlet")
@MultipartConfig(fileSizeThreshold = 1024 * 1024 * 2, // 2MB
		maxFileSize = 1024 * 1024 * 500, // 500MB
		maxRequestSize = 1024 * 1024 * 1024) // 1GB
public class FileUploadServlet extends HttpServlet {
	
	/**
     * Location to save uploaded files on server
     */
	private static final String UPLOAD_PATH = "C:/uploads";
	
	/**
     * Method to get file name from HTTP header content-disposition
     */
	private String getFileName(Part part) {
		String contentDisp = part.getHeader("content-disposition");
		String[] items = contentDisp.split(";");
		for (String s : items) {
			if (s.trim().startsWith("filename")) {
				return s.substring(s.indexOf("=") + 2, s.length() - 1);
			}
		}
		return null;
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		try {
			File uploadsPath = new File(UPLOAD_PATH);
			if (!uploadsPath.exists()) {
				//create upload folder if not exist.
				uploadsPath.mkdir();
			}
			for (Part part : request.getParts()) {
				String fileName = getFileName(part);
				if(fileName!=null) {
					part.write(UPLOAD_PATH + File.separator + fileName);
				}
			}
			System.out.println("File uploaded successfully!");
		} catch (Exception e) {
			System.err.println("Error while uploading files!");
			e.printStackTrace();
		}
	}

}

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.javacodepoint</groupId>
	<artifactId>JavaFileUpload</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>
	<dependencies>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>3.0.1</version>
			<scope>provided</scope>
		</dependency>
	</dependencies>
	<build>
		<sourceDirectory>src</sourceDirectory>
		<plugins>
			<plugin>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.8.1</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
			</plugin>
			<plugin>
				<artifactId>maven-war-plugin</artifactId>
				<version>3.2.3</version>
				<configuration>
					<warSourceDirectory>WebContent</warSourceDirectory>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

Conclusion

In this article, you have seen how Multiple files uploaded in Java can be developed. You have also learned about creating a javascript progress bar user interface to achieve the best user experience while doing multiple file uploads.

To learn more about the server-side implementation you can visit our Article: File Upload in Java Servlet Example.

Create drag and drop file uploader UI to upload single as well as multiple files at a time. Visit another Article: Drag and drop file uploader UI.


Related Articles:

Share with friends

Leave a Comment

Your email address will not be published. Required fields are marked *