Dashboard > WebWork 1 > WebWork CookBook > File Upload Interceptor
  WebWork 1 Log In View a printable version of the current page.  
  File Upload Interceptor
Added by Raymond Lai, last edited by Hani Suleiman on Apr 25, 2004  (view change)
Labels: 
(None)

Jealous of Webwork2's File Upload Interceptor? If you are done with Spring Framework Integration with Webwork, with a little effort you can enjoy the same convenience with the help of Spring's AOP framework.

First, we introduce a new interface for our file upload interceptor to identify and inject the values appropriately.

So, we have UploadFileAware interface:

package webwork.ext.spring;

import java.io.File;

public interface UploadFileAware
{
	public void setFile(File file);
	public void setFilename(String filename);
}

Note: Current codes in Webwork1's CVS contains a new WebworkMultipartRequest parser (internal) which returns uploaded files as temporary files. If you will be using cos or pell's MultipartRequest parser you can omit the setFilename method.

Of course, if your Webwork Action will need to process multiple uploaded files you may have a MultipleUploadFileAware interface which injects an array of Files and Filenames.

Next we have _FileUploadInterceptor_. Of course you can override the values and types of file accepted through configurations at Spring's applicationContext.xml.

package webwork.ext.spring;

import java.io.File;
import java.util.Enumeration;
import webwork.action.ActionContext;
import webwork.config.Configuration;
import webwork.multipart.MultiPartRequestWrapper;
import webwork.action.ServletActionContext;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class FileUploadInterceptor implements MethodInterceptor
{
    private static final String ALL_FILES_ACCEPTED = "*";
    private static final long DEFAULT_MAX_FILE_SIZE = 
      Long.parseLong(Configuration.getString("webwork.multipart.maxSize"));
	
    private String acceptedTypes = ALL_FILES_ACCEPTED;
    private long maxFileSize = DEFAULT_MAX_FILE_SIZE;
    private final Log logger = LogFactory.getLog(getClass());
	
    public void setMaxFileSize(long maxFileSize)
    {
        this.maxFileSize = maxFileSize;
    }
	
    public void setAcceptedTypes(String acceptedTypes)
    {
        this.acceptedTypes = acceptedTypes;
    }

    public Object invoke(MethodInvocation methodInvocation) throws Throwable
    {
        if(methodInvocation.getThis() instanceof UploadFileAware)
        {
            if(logger.isDebugEnabled()) logger.debug("Intercepting call: " + 
                methodInvocation.getMethod().getDeclaringClass() + ":: " + 
                methodInvocation.getMethod().getName()); 
            if (!(ServletActionContext.getRequest() instanceof 
                  MultiPartRequestWrapper))
            {
                return methodInvocation.proceed();
            }

            MultiPartRequestWrapper multiWrapper = 
                (MultiPartRequestWrapper) ServletActionContext.getRequest();
            Enumeration e = multiWrapper.getFileNames();
			
            //bind files to Action
            while(e.hasMoreElements())
            {
                // get the value of this input tag
                String inputName = (String) e.nextElement();
                // get the content type
                String contentType = multiWrapper.getContentType(inputName);
                // get the name of the file from the input tag
                String fileName = multiWrapper.getFilesystemName(inputName);
                // Get a File object for the uploaded File
                File file = multiWrapper.getFile(inputName);
				
                // If it's null the upload failed
                if (file != null)
                {
                    logger.info("file " + inputName + " " + contentType 
                     + " " + fileName + " " + file);
                    if (acceptFile(file, contentType, inputName))
                    {
                        UploadFileAware underlyingAction = 
                            (UploadFileAware)methodInvocation.getThis();
                        underlyingAction.setFile(file);
                        underlyingAction.setFilename(fileName);
                    }
                    // Do additional processing/logging...
                 }				
             }

             //execute
             Object retVal = methodInvocation.proceed();
			
             //cleanups. Uncomment so that the uploaded file will 
             //be removed after the underlying Action is executed
             /*e = multiWrapper.getFileNames();
             while (e.hasMoreElements())
             {
                 String inputValue = (String) e.nextElement();
                 File file = multiWrapper.getFile(inputValue);
                 logger.info("removing file " + inputValue + " " + file);
                 if (file != null && file.isFile()) file.delete();
             }*/			
			
             //return result
             return retVal;
         }
         if(logger.isDebugEnabled()) 
           logger.debug(methodInvocation.getMethod().getDeclaringClass() 
           + ":: " + methodInvocation.getMethod().getName() + " not intercepted");
         return methodInvocation.proceed();
    }

    private boolean acceptFile(File file, String contentType, String inputName)
    {
        //check size
        if(file.length() > maxFileSize)
        {
            if(logger.isDebugEnabled()) 
              logger.debug("Not accepted: File size > max allowed size");
            return false;
        }
        else
	{
            if(acceptedTypes.equals(ALL_FILES_ACCEPTED))
	    {
                if(logger.isDebugEnabled()) logger.debug("accepted");
                return true;
            }
            else
            {
                if(acceptedTypes.indexOf(contentType) < 0)
                {
                    if(logger.isDebugEnabled()) logger.debug("accepted: " + 
                       contentType);
                    return true;
                }
                if(logger.isDebugEnabled()) logger.debug("not accepted: " + 
                   contentType);
                return false;
            }
        }
    }
}

Again, this interceptor process single uploaded file only. However you can modify it to process multiple uploaded files with a little effort.

In the Action using the file upload interceptor just need to implement the UploadFileAware interface:

....
import java.io.File;
import webwork.action.ActionSupport;
import webwork.ext.spring.UploadFileAware;

public class MyAction extends ActionSupport implements UploadFileAware
{
    private File uploadedFile;
    private String uploadedFilename;

    public void setFile(File file)
    {
        this.uploadedFile = file;
    }

    public void setFilename(String filename)
    {
        this.uploadedFilename = filename;
    }

    public String execute()
    {
        ....
        //Move the uploaded file to our specified location.
        uploadedFile.renameTo(new File(ApplicationSettings.DEFAULT_IMAGE_DIRECTORY 
          + File.separator + uploadedFilename));
        ....
    }
    ....
}

Last step we just need to configure the collaborations between the interceptor and the WW Action on _applicationContext.xml_. Here we follow the way we did at Spring Framework Integration.

<bean id="fileUploadInterceptor" 
   class="webwork.ext.spring.FileUploadInterceptor" />

<bean id="fileUploadInterceptorAdvice" 
   class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
    <property name="advice">
        <ref local="fileUploadInterceptor"/>
    </property>
    <property name="mappedName">
        <value>execute</value>
    </property>
</bean>

<bean id="proxyCreator" 
class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
    <property name="proxyTargetClass"><value>true</value></property>
    <property name="interceptorNames">
        <list>
            <value>fileUploadInterceptorAdvice</value>
        </list>
    </property>
    <property name="beanNames">
        <list>
            <value>MyAction</value>
        </list>
    </property>
</bean>

<bean id="MyAction" class="MyAction" singleton="false" />

Now you can free your Actions from doing the dirty laundry of processing uploaded files!

If we want to upload file to another directory/folder instead of temp, how can we do that?

Thanks!

Posted by Thanh at Aug 06, 2004 07:03 | Permalink
Site powered by a free Open Source Project / Non-profit License (more) of Confluence - the Enterprise wiki.
Learn more or evaluate Confluence for your organisation.
Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.2.9 Build:#527 Sep 07, 2006) - Bug/feature request - Contact Administrators