Introduction
In this tutorial you will learn about Asynchronous File Upload using Ajax, jQuery Progress Bar and Java
The image below shows a screenshot of the file upload that we are going to learn in this tutorial.
also read:
Let us see what all is needed to develop this application. We shall create a web application which has the following files.
- FileUpload.html (The html/jsp file where the file upload happens)
- jQuery related script files(We are going to discuss about this in detail later)
- FileUploadListener.java(The listener file which listens to the file upload)
- FileUploadListener.java (The servlet file which takes care of the upload process)
- web.xml
The image below shows the screenshot of the file Structure. We have used netBeans IDE to develop the web Application.
File Structure
Let us try to understand the webstructure.We have a web folder which has FileUpload.html.The source packages has a java package “fileupload” which has two java files FileUploadListener.java and FileUploadServlet.java
There is another folder called “scripts” which has jquery.js which is used for the core javascript and Ajax features of jQuery library.
Apart from this we also have ui.core.js and ui.progressbar.js. These files are necessary for constructing a progress bar using jQuery.You can download the latest version of jQuery from Download jQuery
The jquery progress bar can be downloaded from Download jQuery UI
Now let us add in code into FileUpload.html
We shall be adding script , style and html body sections to the html files. Lets deal with each one of these sections one after the other.
Please find below the code for the html body section.
Html Body Code
<body> <center> <h2 class="backgroundClass">Sample File Upload</h2> <form id="myForm" enctype="multipart/form-data" method="post" target="uploadFrame" action="example/FileUploadServlet" onsubmit="ajaxFunction()"> <table border="1"> <tr><td> <h4>File to be uploaded </h4></td><td> <input type="file" name="txtFile" id="txtFile" /></td></tr> <tr><td align="center" colspan="2"> <input type="submit" id="submitID" name="submit" value="Upload" /></td></tr> </table> </form> <div id="progressbarWrapper" style="height:20px;width:100px; "> <div id="progressbar" style="height:100%;"></div> </div> <br/> <div id="status" style="display:none"> <table width="100%" class="backgroundClass"> <tr> <td align="center" nowrap="nowrap"> <div id="percentDone" style="font-weight: bold;"> </span> </td> </tr> </table> <table width="100%" class="backgroundClass"> <tr> <td align="center" nowrap="nowrap"> <div id="bytesRead" style="font-weight: bold;"> </span> </td> </tr> </table> <table width="100%" class="backgroundClass"> <tr> <td align="center" nowrap="nowrap"> <div id="totalNoOfBytes" style="font-weight: bold;"> </span> </td> </tr> </table> </div> </center> </body>
Script Code
Add the following code to the script section.
The script code pasted below will import the various script files necessary for jQuery core functions, progress bar and Ajax.
After importing, we need to do the following tasks:
- Add the progressbar to the page(The progress bar will be hidden on the load of the page and will be shown only when the file upload begins.)
- Make an Ajax request to the java Servlet(Servlet code will be discussed later).The Java Servlet will take care of the file upload on the server.
- The ajaxFunction() will take care of sending the xmlHttpRequest.
- funcReadyStateChange() will be invoked soon after getting the output.It takes care of the collecting the servlet output which is in the form of XML.funcReadyStateChange()will also take care of:
- Parsing the response XML.
- Updating the progress bar value through updateProgressbar() function
- Update the page with the response.
- The output xml will have details about the total number of bytes present in the file and the number of bytes uploaded.
- Please note that the funcReadyState will make repetitive calls to ajaxFunction() and updateProgressBar() until the file is completely uploaded.Every request that is sent will get the recent most values of the “number of bytes that are uploaded” from the server.
<script src="scripts/jquery.js"></script> <script src="scripts/ui.core.js"></script> <script src="scripts/ui.progressbar.js"></script> <script src="scripts/ui.resizable.js"></script> <script> var progressBarValue=0; $(document).ready(function() { $( "#progressbar" ).progressbar({ value:0 }); document.getElementById("progressbarWrapper").style.display = "none"; }); function updateProgressBar(progressBarValue) { $("#progressbar").progressbar("option","value",progressBarValue); } var req; function ajaxFunction(){ var url = "example/FileUploadServlet"; if (window.XMLHttpRequest){ req = new XMLHttpRequest(); try{ req.onreadystatechange = funcReadyStateChange; req.open("GET", url, true); } catch (e) { alert(e); } req.send(null); } else if (window.ActiveXObject) { req = new ActiveXObject("Microsoft.XMLHTTP"); if (req) { req.onreadystatechange = funcReadyStateChange; req.open("GET", url, true); req.send(); } } } function funcReadyStateChange(){ if (req.readyState == 4){ if (req.status == 200){ var xml = req.responseXML; var responseNode=xml.getElementsByTagName("response")[0]; var noOfBytesRead =responseNode.getElementsByTagName("bytes_read")[0]. childNodes[0].nodeValue; var totalNoOfBytes = responseNode.getElementsByTagName("content_length")[0]. childNodes[0].nodeValue; progressBarValue=noOfBytesRead/totalNoOfBytes*100; document.getElementById("status").style.display="block"; document.getElementById("percentDone").innerHTML="Percentage Completed: " +Math.floor(progressBarValue)+"%"; document.getElementById("bytesRead").innerHTML= "Number Of Bytes Read: "+ noOfBytesRead; document.getElementById("totalNoOfBytes").innerHTML= "Total Number Of Bytes: "+ totalNoOfBytes; document.getElementById("progressbarWrapper").style.display = "block"; if (progressBarValue<100){ window.setTimeout("ajaxFunction();", 100); window.setTimeout("updateProgressBar(progressBarValue);", 100); } else { alert("Done"); window.setTimeout("updateProgressBar(100);", 100); document.getElementById("progressbarWrapper").style.display = "none"; document.getElementById("status").style.display="none"; } } else { alert(req.statusText); } } } </script>
Style Code
Now add the following code to the style section.
<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css" rel="stylesheet" type="text/css"/> <link href="style/ui.all.css" rel="stylesheet" type="text/css"/> <link href="style/ui.core.css" rel="stylesheet" type="text/css"/> <link href="style/ui.progressbar.css" rel="stylesheet" type="text/css"/> <style type="text/css"> .ui-progressbar-value { background-image: url(images/progressBarImage.jpg); } .backgroundClass { background-image: url(images/background.jpg); color:white; } </style>
Listener Code
This listener will listen to the event of file upload and has a method called fileUpdate() which will be automatically invoked as and when there is an update on fileUpload.
package fileupload; import org.apache.commons.fileupload.ProgressListener; public class FileUploadListener implements ProgressListener{ private volatile long bytesRead = 0L, contentLength = 0L, item = 0L; public FileUploadListener() { super(); } public void update(long aBytesRead, long aContentLength, int anItem) { bytesRead = aBytesRead; contentLength = aContentLength; item = anItem; } public long getBytesRead() { return bytesRead; } public long getContentLength() { return contentLength; } public long getItem() { return item; } }
Servlet Code
The servlet will get the information about the number of bytes read through the listener and will construct a response xml with tags “bytes-read” and “content-length” etc.
package fileupload; import javax.servlet.Servlet; import javax.servlet.http.HttpServlet; import java.io.*; import java.util.*; import javax.servlet.http.*; import org.apache.commons.fileupload.*; import javax.servlet.ServletException; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; public class FileUploadServlet extends HttpServlet implements Servlet { private static final long serialVersionUID = 2740693677625051632L; public FileUploadServlet() { super(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter out = response.getWriter(); HttpSession session = request.getSession(); FileUploadListener listener = null; StringBuffer buffy = new StringBuffer(); long bytesRead = 0, contentLength = 0; if (session == null) { return; } else if (session != null) { listener = (FileUploadListener) session.getAttribute("LISTENER"); if (listener == null) { return; } else { bytesRead = listener.getBytesRead(); contentLength = listener.getContentLength(); } } response.setContentType("text/xml"); buffy.append("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"); buffy.append("<response>\n"); buffy.append("\t<bytes_read>" + bytesRead + "</bytes_read>\n"); buffy.append("\t<content_length>" + contentLength + "</content_length>\n"); if (bytesRead == contentLength) { buffy.append("\t<finished />\n"); session.setAttribute("LISTENER", null); } else { long percentComplete = ((100 * bytesRead) / contentLength); buffy.append("\t<percent_complete>" + percentComplete + "</percent_complete>\n"); } buffy.append("</response>\n"); out.println(buffy.toString()); out.flush(); out.close(); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { FileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload upload = new ServletFileUpload(factory); FileUploadListener listener = new FileUploadListener(); HttpSession session = request.getSession(); session.setAttribute("LISTENER", listener); upload.setProgressListener(listener); List uploadedItems = null; FileItem fileItem = null; String filePath = "c:\\temp"; try { uploadedItems = upload.parseRequest(request); Iterator i = uploadedItems.iterator(); while (i.hasNext()) { fileItem = (FileItem) i.next(); if (fileItem.isFormField() == false) { if (fileItem.getSize() > 0) { File uploadedFile = null; String myFullFileName = fileItem.getName(), myFileName = "", slashType = (myFullFileName.lastIndexOf("\\") > 0) ? "\\" : "/"; int startIndex = myFullFileName.lastIndexOf(slashType); myFileName = myFullFileName.substring(startIndex + 1, myFullFileName.length()); uploadedFile = new File(filePath, myFileName); fileItem.write(uploadedFile); } } } } catch (FileUploadException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } }
web.xml
We need to declare the servlet and also the listener in web.xml.
<servlet> <servlet-name>UploadServlet </servlet-name> <servlet-class>fileupload.FileUploadServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>UploadServlet</servlet-name> <url-pattern>/example/FileUploadServlet</url-pattern> </servlet-mapping> <listener> <listener-class>fileupload.FileUploadListener</listener-class> </listener>
also read:
Conclusion
In this tutorial , we have seen how to upload a file when we have java on the server side.
We have also seen how to do the same using jQuery-Ajax and jQuery progress bar.