Java Servlet & JSP Cookbook
Problem
You want to create a component that can receive a client file upload and store the file in a local directory. Solution
Create a servlet that uses the com.oreilly.servlet.MultipartRequest class from Jason Hunter's cos.jar archive. Discussion
The MultipartRequest class includes several overloaded constructors. The one used in Example 8-3 takes the javax.servlet.http.HttpServletRequest object, the path to the directory where you want to save uploaded files, and the size limit for the file as parameters. In Example 8-3, if the client uploads a file that exceeds 5 MB, then the UploadServlet throws a java.io.IOException . You can allow this exception to be managed by an error-page element in web.xml for IOExceptions , as Example 8-3 does, or use a try/catch block in the upload servlet to deal with errors.
With MultipartRequest , as soon as the code instantiates the object, the object is handling the file upload; in other words, you do not have to call a method to commence managing the upload. The servlet in Example 8-3 initiates the file upload and then displays the name of the uploaded file(s). Example 8-3. A servlet that uses the MultipartRequest class
package com.jspservletcookbook; import javax.servlet.*; import javax.servlet.http.*; import com.oreilly.servlet.MultipartRequest; import java.util.Enumeration; public class UploadServlet extends HttpServlet { private String webTempPath; public void init( ) webTempPath = getServletContext( ).getRealPath("/") + "data"; } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, java.io.IOException { //file limit size of 5 MB MultipartRequest mpr = new MultipartRequest( request,webTempPath,5 * 1024 * 1024); Enumeration enum = mpr.getFileNames( ); response.setContentType("text/html"); java.io.PrintWriter out = response.getWriter( ); out.println("<html>"); out.println("<head>"); out.println("<title>Servlet upload</title>"); out.println("</head>"); out.println("<body>"); for (int i = 1; enum.hasMoreElements( );i++) out.println("The name of uploaded file " + i + " is: " + mpr.getFilesystemName((String) enum.nextElement( )) + "<br><br>"); out.println("</body>"); out.println("</html>"); } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, java.io.IOException { throw new ServletException("GET method used with " + getClass( ).getName( )+": POST method required."); } } The code generates the path to the save directory by calling javax.servlet.ServletContext.getRealPath("/") to get an absolute pathname to the root of the web application (as in h:\home\ ). Then the code adds the name of the directory where the file will be saved ( data ).
The method MultipartRequest.getFilesystemName( StringName ) returns the filename from the client's filesystem. The file can be saved on the server end with its original filename, or you can use a different MultipartRequest constructor that takes as a parameter a FileRenamePolicy object. This constructor looks like: MultipartRequest(javax.servlet.http.HttpServletRequest request, java.lang.String saveDirectory, int maxPostSize, FileRenamePolicy policy) There are a few versions of the MultipartRequest constructor with the FileRenamePolicy parameter, which is used to rename uploaded files (see Recipe 8.5). Example 8-3 also throws a ServletException if the UploadServlet is requested with a GET method, which is not allowed with file uploads. See Also
Recipe 8.1 on preparing the HTML for a file upload; Recipe 8.4 on downloading and using the com.oreilly.servlet library; Recipe 8.6 on handling multiple file uploads in a servlet; Recipe 8.5 on controlling file naming during file uploads; Recipe 8.6 on using a JSP to handle file uploads; the homepage for com.oreilly.servlet : http://www.servlets.com/cos/index.html; the RFC 1867 document on form-based file uploads: http://www.ietf.org/rfc/rfc1867.txt. |