Commits

Anonymous committed db497cb

WW-567: FileUploadInterceptor

git-svn-id: http://svn.opensymphony.com/svn/webwork/trunk@457573baa09-0c28-0410-bef9-dab3c582ae83

Comments (0)

Files changed (3)

src/java/com/opensymphony/webwork/dispatcher/multipart/MultiPartRequestWrapper.java

 package com.opensymphony.webwork.dispatcher.multipart;
 
 import com.opensymphony.webwork.config.Configuration;
-
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
 import java.io.File;
 import java.io.IOException;
-
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Vector;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletRequestWrapper;
+import java.util.*;
 
 
 /**
  * Parses a multipart request and provides a wrapper around the request. The parsing implementation used
  * depends on the <tt>webwork.multipart.parser</tt> setting. It should be set to a class which
  * extends {@link com.opensymphony.webwork.dispatcher.multipart.MultiPartRequest}. <p>
- *
+ * <p/>
  * Webwork ships with two implementations,
  * {@link com.opensymphony.webwork.dispatcher.multipart.PellMultiPartRequest} and
  * {@link com.opensymphony.webwork.dispatcher.multipart.CosMultiPartRequest}. The Pell implementation
  * is the default. The <tt>webwork.multipart.parser</tt> property should be set to <tt>pell</tt> for
  * the Pell implementation and <tt>cos</tt> for the Jason Hunter implementation. <p>
- *
+ * <p/>
  * The files are uploaded when the object is instantiated. If there are any errors they are logged using
  * {@link #addError(String)}. An action handling a multipart form should first check {@link #hasErrors()}
  * before doing any other processing. <p>
             // If it's not set, use Pell
             if (parser.equals("")) {
                 log.warn("Property webwork.multipart.parser not set." + " Using com.opensymphony.webwork.dispatcher.multipart.PellMultiPartRequest");
-                parser = "com.opensymphony.webwork.dispatcher.multipart.PellMultiPartRequest";
+                parser = com.opensymphony.webwork.dispatcher.multipart.PellMultiPartRequest.class.getName();
             }
 
             // legacy support for old style property values
             if (parser.equals("pell")) {
-                parser = "com.opensymphony.webwork.dispatcher.multipart.PellMultiPartRequest";
+                parser = com.opensymphony.webwork.dispatcher.multipart.PellMultiPartRequest.class.getName();
             } else if (parser.equals("cos")) {
-                parser = "com.opensymphony.webwork.dispatcher.multipart.CosMultiPartRequest";
+                parser = com.opensymphony.webwork.dispatcher.multipart.CosMultiPartRequest.class.getName();
             }
 
             try {
                 }
 
                 // get the constructor
-                Constructor ctor = clazz.getDeclaredConstructor(new Class[] {
-                        Class.forName("javax.servlet.http.HttpServletRequest"),
-                        java.lang.String.class, int.class
-                    });
+                Constructor ctor = clazz.getDeclaredConstructor(new Class[]{
+                    Class.forName("javax.servlet.http.HttpServletRequest"),
+                    java.lang.String.class, int.class
+                });
 
                 // build the parameter list
-                Object[] parms = new Object[] {
+                Object[] parms = new Object[]{
                     request, saveDir, new Integer(maxSize)
                 };
 

src/java/com/opensymphony/webwork/interceptor/FileUploadInterceptor.java

+package com.opensymphony.webwork.interceptor;
+
+import com.opensymphony.webwork.ServletActionContext;
+import com.opensymphony.webwork.dispatcher.multipart.MultiPartRequestWrapper;
+import com.opensymphony.xwork.Action;
+import com.opensymphony.xwork.ActionInvocation;
+import com.opensymphony.xwork.ValidationAware;
+import com.opensymphony.xwork.interceptor.Interceptor;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.io.File;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.Iterator;
+
+/**
+ * Interceptor that is based off of {@link MultiPartRequestWrapper}. It adds the following
+ * parameters, where [File Name] is the name given to the file uploaded by the HTML form:
+ * <ul>
+ * <li>[File Name] : File - the actual File</li>
+ * <li>[File Name]ContentType : String - the content type of the file</li>
+ * <li>[File Name]FileName : String - the actual name of the file uploaded (not the HTML name)</li>
+ * </ul>
+ * <p/>
+ * You can get access to these files by merely providing setters in your action that coorespond to any
+ * of the three patterns above, such as setDocument(File document), setDocumentContentType(String contentType), etc.
+ */
+public class FileUploadInterceptor implements Interceptor {
+    protected static final Log log = LogFactory.getLog(FileUploadInterceptor.class);
+
+    protected String allowedTypes;
+    protected String disallowedTypes;
+    protected Long maximumSize;
+
+    public void init() {
+    }
+
+    public void destroy() {
+    }
+
+    public void setAllowedTypes(String allowedTypes) {
+        this.allowedTypes = allowedTypes;
+    }
+
+    public void setDisallowedTypes(String disallowedTypes) {
+        this.disallowedTypes = disallowedTypes;
+    }
+
+    public void setMaximumSize(Long maximumSize) {
+        this.maximumSize = maximumSize;
+    }
+
+    public String intercept(ActionInvocation invocation) throws Exception {
+        if (!(ServletActionContext.getRequest() instanceof MultiPartRequestWrapper)) {
+            if (log.isDebugEnabled()) {
+                log.debug("bypass " + invocation.getProxy().getNamespace() + "/" + invocation.getProxy().getActionName());
+            }
+
+            return invocation.invoke();
+        }
+
+        ValidationAware validation = null;
+        Action action = invocation.getAction();
+        if (action instanceof ValidationAware) {
+            validation = (ValidationAware) action;
+        }
+
+        MultiPartRequestWrapper multiWrapper = (MultiPartRequestWrapper) ServletActionContext.getRequest();
+        if (multiWrapper.hasErrors()) {
+            Collection errors = multiWrapper.getErrors();
+            Iterator i = errors.iterator();
+            while (i.hasNext()) {
+                String error = (String) i.next();
+
+                if (validation != null) {
+                    validation.addActionError(error);
+                }
+
+                log.error(error);
+            }
+        }
+
+        Enumeration e = multiWrapper.getFileNames();
+
+        // Bind allowed Files
+        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);
+
+            log.info("file " + inputName + " " + contentType + " " + fileName + " " + file);
+
+            // If it's null the upload failed
+            if (file == null) {
+                if (validation != null) {
+                    validation.addFieldError(inputName, "Could not upload file. Perhaps it is too large?");
+                }
+
+                log.error("Error uploading: " + fileName);
+            } else {
+                invocation.getInvocationContext().getParameters().put(inputName, file);
+                invocation.getInvocationContext().getParameters().put(inputName + "ContentType", contentType);
+                invocation.getInvocationContext().getParameters().put(inputName + "FileName", fileName);
+            }
+        }
+
+        // invoke action
+        String result = invocation.invoke();
+
+        // cleanup
+        e = multiWrapper.getFileNames();
+        while (e.hasMoreElements()) {
+            String inputValue = (String) e.nextElement();
+            File file = multiWrapper.getFile(inputValue);
+            log.info("removing file " + inputValue + " " + file);
+            if (file != null && file.isFile()) file.delete();
+        }
+
+        return result;
+    }
+}

src/java/webwork-default.xml

             <result-type name="chain" class="com.opensymphony.xwork.ActionChainResult"/>
             <result-type name="xslt" class="com.opensymphony.webwork.views.xslt.XSLTResult"/>
             <result-type name="jasper" class="com.opensymphony.webwork.views.jasperreports.JasperReportsResult"/>
-			<result-type name="freemarker" class="com.opensymphony.webwork.views.freemarker.FreemarkerResult"/>
+            <result-type name="freemarker" class="com.opensymphony.webwork.views.freemarker.FreemarkerResult"/>
         </result-types>
 
         <interceptors>
             <interceptor name="servlet-config" class="com.opensymphony.webwork.interceptor.ServletConfigInterceptor"/>
             <interceptor name="prepare" class="com.opensymphony.xwork.interceptor.PrepareInterceptor"/>
             <interceptor name="conversionError" class="com.opensymphony.webwork.interceptor.WebWorkConversionErrorInterceptor"/>
+            <interceptor name="fileUpload" class="com.opensymphony.webwork.interceptor.FileUploadInterceptor"/>
             <interceptor-stack name="defaultStack">
                 <interceptor-ref name="static-params"/>
                 <interceptor-ref name="params"/>