[ Team LiB ] Previous Section Next Section

Recipe 8.3 Uploading One File at a Time

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.

See Chapter 9 for how to declare error pages for the web application.


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).

This directory name could also be added using an external configuration such as a context-param element in web.xml. See Recipe 8.6 for details.


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.

    [ Team LiB ] Previous Section Next Section