[ Team LiB ] Previous Section Next Section

Recipe 8.5 Renaming Files

Problem

You want to rename the uploaded files according to a standard policy or to avoid conflicts with existing files that have the same name.

Solution

Create a class that implements the com.oreilly.servlet.multipart.FileRenamePolicy interface, or use the DefaultFileRenamePolicy class. Then use that class as a parameter in the constructor for the com.oreilly.servlet.MultipartRequest class.

Discussion

The com.oreilly.servlet.multipart package contains a FileRenamePolicy interface that can be used when you want to implement a particular file-renaming policy with file uploads.

The DefaultFileRenamePolicy class renames an uploaded file whose name conflicts with an existing file by adding a number to the uploaded filename. For example, if index.txt already exists, then the DefaultFileRenamePolicy class renames the uploaded file index1.txt; and if a second file is uploaded with the same name it will be renamed index2.txt, and so on.

If you want to implement your own renaming policy, then create your own class that implements the FileRenamePolicy interface, then implement the class's rename(java.io.File file) method to initiate the renaming action.

This code sample shows a MultipartRequest constructor from Example 8-3. This time, the constructor adds a DefaultFileRenamePolicy object as a constructor parameter:

MultipartRequest mpr = new MultipartRequest(
  request,webTempPath,(5 * 1024 * 1024),new DefaultFileRenamePolicy( ));

Make sure to include the following import statements in the servlet class:

import com.oreilly.servlet.MultipartRequest;
import com.oreilly.servlet.multipart.DefaultFileRenamePolicy;

As mentioned before, you can implement the FileRenamePolicy interface yourself and create a custom file-renaming mechanism. Example 8-5 shows a MyFileRenamePolicy class that renames each uploaded file by appending a timestamp to the end of its name. The simple timestamp is calculated as:

// seconds since Jan 1, 1970, 00:00:00
new java.util.Date( ).getTime( ) / 1000

The code renames the file by appending the String (representing a series of numbers) to the filename minus its extension, and then appending the extension at the end (if the filename originally had an extension).

Example 8-5. Renaming uploaded files with your own Java class
package com.jspservletcookbook;

import java.io.File;
import java.util.Date;
 
import com.oreilly.servlet.multipart.FileRenamePolicy;

public class MyFileRenamePolicy implements FileRenamePolicy {
    
    //implement the rename(File f) method to satisfy the 
    // FileRenamePolicy interface contract
    public File rename(File f){
    
        //Get the parent directory path as in h:/home/user or /home/user
        String parentDir = f.getParent( );
      
        //Get filename without its path location, such as 'index.txt'
        String fname = f.getName( );
      
        //Get the extension if the file has one
        String fileExt = "";
        int i = -1;
        if(( i = fname.indexOf(".")) != -1){
      
            fileExt = fname.substring(i);
            fname = fname.substring(0,i);
        }
      
        //add the timestamp
        fname = fname + (""+( new Date( ).getTime( ) / 1000));
      
        //piece together the filename
        fname = parentDir + System.getProperty(
            "file.separator") + fname + fileExt;
      
        File temp = new File(fname);
 
         return temp;
    }

}

Given that your new class is called com.jspservletcookbook.MyFileRenamePolicy and implements the FileRenamePolicy interface, the constructor for the MultipartRequest would now look like this:

MultipartRequest mpr = new MultipartRequest(
  request,webTempPath,(5 * 1024 * 1024),
    new com.jspservletcookbook.MyFileRenamePolicy( ));

Store your new class in the WEB-INF/classes directory of the web application using the same directory structure as the class's package name (as in WEB-INF/classes/com/jspservletcookbook/MyFileRenamePolicy.class).

In general, the com.oreilly.servlet package also includes the MultipartFilter class. According to an article that Jason has written (http://www.servlets.com/soapbox/filters.html), "The MultipartFilter works by watching incoming requests and when it detects a file upload request (with the content type multipart/form-data), the filter wraps the request object with a special request wrapper that knows how to parse the special content type format."


See Also

Recipe 8.1 on preparing HTML for a file upload; Recipe 8.4 on downloading and using the com.oreilly.servlet library; Recipe 8.3 and Recipe 8.6 on handling single- and multiple-file uploads in a servlet; 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