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


Page:    1 2 >

In another tutorial, we saw how we could work with a set of files uploaded to a servletW (TestServlet) from a JSPW (upload.jsp) using the ApacheSW Commons FileUploadS library. Sometimes, if a large file or set of files is being uploaded, it can be nice to inform a user as to the status of the file upload. This tutorial will show a basic version of how we can use a ProgressListener to monitor the status of the file upload.

The project that we'll use has the following structure. It utilizes the Commons FileUpload and Commons IOS libraries from Apache. It features upload.jsp (the jspW containing the form to upload our files), TestServlet (the servlet to which we upload our files), TestProgressListener (the listener that monitors the status of the upload), and ProgressServlet (the servlet that displays the status of the upload).

'file-upload' project

The upload.jsp file contains a "multipart/form-data" form that submits its form data to "test", which maps to our TestServlet class.

upload.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Upload Page</title>
</head>
<body>
	<form name="form1" id="form1" action="test" method="post" enctype="multipart/form-data">
	<input type="hidden" name="hiddenfield1" value="ok">
	Files to upload:
	<br/>
	<input type="file" size="50" name="file1">
	<br/>
	<input type="file" size="50" name="file2">
	<br/>
	<input type="file" size="50" name="file3">
	<br/>
	<input type="submit" value="Upload">
	</form>
</body>
</html>

The project's web.xmlW file has two servletsW and two servlet mappings. Requests to "/test" map to the TestServlet class and requests to "/progress" map to the ProgressServlet class.

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="file-upload" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
	<servlet>
		<servlet-name>TestServlet</servlet-name>
		<servlet-class>test.TestServlet</servlet-class>
	</servlet>
	<servlet>
		<servlet-name>ProgressServlet</servlet-name>
		<servlet-class>test.ProgressServlet</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>TestServlet</servlet-name>
		<url-pattern>/test</url-pattern>
	</servlet-mapping>
	<servlet-mapping>
		<servlet-name>ProgressServlet</servlet-name>
		<url-pattern>/progress</url-pattern>
	</servlet-mapping>
</web-app>

The TestServlet class is shown below. If multipart form content is present, the servlet creates a DiskFileItemFactory object and a ServletFileUpload object. The monitoring 'magic' occurs when we create a TestProgressListener object and call upload.setProgressListener(testProgressListener). This 'registers' testProgressListener with the ServletFileUpload object. Thus, while our upload is being managed by the ServletFileUpload object, it informs the progress listener as to the current status of the upload. I put the testProgressListener object in the session via session.setAttribute("testProgressListener", testProgressListener) that that it could be utilized from elsewhere at different times in the application.

TestServlet.java

package test;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.List;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

public class TestServlet extends HttpServlet {

	private static final long serialVersionUID = 1L;
//	public static final long MAX_UPLOAD_IN_MEGS = 50;

	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();

		out.println("Hello<br/>");

		boolean isMultipartContent = ServletFileUpload.isMultipartContent(request);
		if (!isMultipartContent) {
			out.println("You are not trying to upload<br/>");
			return;
		}
		out.println("You are trying to upload<br/>");

		FileItemFactory factory = new DiskFileItemFactory();
		ServletFileUpload upload = new ServletFileUpload(factory);
//		upload.setSizeMax(MAX_UPLOAD_IN_MEGS * 1024 * 1024);
		
		TestProgressListener testProgressListener = new TestProgressListener();
		upload.setProgressListener(testProgressListener);

		HttpSession session = request.getSession();
		session.setAttribute("testProgressListener", testProgressListener);
		
		try {
			List<FileItem> fields = upload.parseRequest(request);
			out.println("Number of fields: " + fields.size() + "<br/><br/>");
			Iterator<FileItem> it = fields.iterator();
			if (!it.hasNext()) {
				out.println("No fields found");
				return;
			}
			out.println("<table border=\"1\">");
			while (it.hasNext()) {
				out.println("<tr>");
				FileItem fileItem = it.next();
				boolean isFormField = fileItem.isFormField();
				if (isFormField) {
					out.println("<td>regular form field</td><td>FIELD NAME: " + fileItem.getFieldName() + 
							"<br/>STRING: " + fileItem.getString()
							);
					out.println("</td>");
				} else {
					out.println("<td>file form field</td><td>FIELD NAME: " + fileItem.getFieldName() +
//							"<br/>STRING: " + fileItem.getString() +
							"<br/>NAME: " + fileItem.getName() +
							"<br/>CONTENT TYPE: " + fileItem.getContentType() +
							"<br/>SIZE (BYTES): " + fileItem.getSize() +
							"<br/>TO STRING: " + fileItem.toString()
							);
					out.println("</td>");
				}
				out.println("</tr>");
			}
			out.println("</table>");
		} catch (FileUploadException e) {
			out.println("Error: " + e.getMessage());
			e.printStackTrace();
		}
	}
}

(Continued on page 2)

Page:    1 2 >