How do I monitor the progress of a file upload to a servlet?
Author: Deron Eriksson
Description: This tutorial describes how to monitor the progress of a file upload to a servlet.
Tutorial created using:
Windows XP || JDK 1.5.0_09 || Eclipse Web Tools Platform 2.0 (Eclipse 3.3.0) || Tomcat 5.5.20
(Continued from page 1) The TestProgressListener class implements the ProgressListener interface, which requires our class to implement the update() method. This method takes in three parameters. The first parameter is the number of bytes read so far. The second parameter is the total content length, if available. If it is not available, it has a value of -1. The third parameter is the current form item number being read by the servletW. For efficiency, this method has a section of code that only executes about every 100,000 bytes. Each time this section of code executes, it displays a status message to standard output. TestProgressListener.javapackage test; import org.apache.commons.fileupload.ProgressListener; public class TestProgressListener implements ProgressListener { private long num100Ks = 0; private long theBytesRead = 0; private long theContentLength = -1; private int whichItem = 0; private int percentDone = 0; private boolean contentLengthKnown = false; public void update(long bytesRead, long contentLength, int items) { if (contentLength > -1) { contentLengthKnown = true; } theBytesRead = bytesRead; theContentLength = contentLength; whichItem = items; long nowNum100Ks = bytesRead / 100000; // Only run this code once every 100K if (nowNum100Ks > num100Ks) { num100Ks = nowNum100Ks; if (contentLengthKnown) { percentDone = (int) Math.round(100.00 * bytesRead / contentLength); } System.out.println(getMessage()); } } public String getMessage() { if (theContentLength == -1) { return "" + theBytesRead + " of Unknown-Total bytes have been read."; } else { return "" + theBytesRead + " of " + theContentLength + " bytes have been read (" + percentDone + "% done)."; } } public long getNum100Ks() { return num100Ks; } public void setNum100Ks(long num100Ks) { this.num100Ks = num100Ks; } public long getTheBytesRead() { return theBytesRead; } public void setTheBytesRead(long theBytesRead) { this.theBytesRead = theBytesRead; } public long getTheContentLength() { return theContentLength; } public void setTheContentLength(long theContentLength) { this.theContentLength = theContentLength; } public int getWhichItem() { return whichItem; } public void setWhichItem(int whichItem) { this.whichItem = whichItem; } public int getPercentDone() { return percentDone; } public void setPercentDone(int percentDone) { this.percentDone = percentDone; } public boolean isContentLengthKnown() { return contentLengthKnown; } public void setContentLengthKnown(boolean contentLengthKnown) { this.contentLengthKnown = contentLengthKnown; } } For a simpler version of a ProgressListener, please see http://commons.apache.org/fileupload/using.html. The ProgressServlet class allows us to display the current upload progress in a browser window. It does this by reading the testProgressListener object that was placed in the session by TestServlet. It calls the getMessage() method on the testProgressListener object and outputs this to the response. ProgressServlet.javapackage test; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; public class ProgressServlet extends HttpServlet { private static final long serialVersionUID = 1L; public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { doPost(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); HttpSession session = request.getSession(true); if (session == null) { out.println("Sorry, session is null"); // just to be safe return; } TestProgressListener testProgressListener = (TestProgressListener) session.getAttribute("testProgressListener"); if (testProgressListener == null) { out.println("Progress listener is null"); return; } out.println(testProgressListener.getMessage()); } } If we start out application and hit the ProgressServlet, we see that the ProgressListener object in the session is currently null since it hasn't been set yet by TestServlet. ![]() I opened a second tab in my browser and opened the upload.jsp file. I selected a 500+ megabyte file called "BigFile.mp3" from my desktop as the first file to upload and I left the other fields blank. I clicked the Upload button to upload the file to TestServlet. ![]() If I go back to my other tab that displays the the results from the ProgressServlet and hit the "Refresh" button in the browser, I can see that when I refreshed, 23% of the upload had been completed. ![]() After a final refresh, we can see that the file has completed its upload. ![]() As a further example, if we examine our Console view showing standard output, we can see the upload status messages that are written about every 100K. ![]() The ProgressListener interface makes it very easy to monitor the status of an upload to a JavaSW web application. This example demonstrates the basics of how the status of an upload can be monitored using a ProgressListener. If we couple this example with some AjaxW, we could display the file upload status on the same page as our upload.jsp, and we could display a progress bar that dynamically refreshes as our upload progresses. |