`

WebWork 2 : File Upload Interceptor

阅读更多
This page last changed on Nov 30, 2004 by jcarreira.

We can create a nice reusable Interceptor which can hadle file uploads absolutely transparently and Action will not know anything about web-app and just gets its files:

  1. Before further invocation it scans multipart request for files, and if content-type and size is acceptable it puts collected java.io.File instance to invocationContext.parameters Map named according to their <input> names.
  2. In Action we can just declare properties of type File which will be set by parameters Inteceptor, in execute() we can move file with aFile.renameTo(...) to the right place, or just read the it and leave alone.
  3. After invocation it removes all uploaded files via aFile.delete(). (Action should not care for iles uploaded waste disk space)

This Interceptor may be configured to filter files with certain mime type or size, and of course to be applied to any action(s) or even included into stack.

 

<interceptor name="fileUpload" class="neuro.util.xwork.FileUploadInterceptor">
    <param name="allowedTypes">image/jpeg</param>
    <param name="maximumSize">8192</param>
</interceptor>

This removes (duplicate) web-app specific code from Action and gives ua a nice reusable component that handles 90% of all typical file upload tasks. Neat. Also illustrates power of Interceptor concept of XW:XWork/WW:WebWork. Try to do this in Struts. 8)

Things to improve: error handling, reporting & i18n.
//FileUploadInterceptor.java

package neuro.util.xwork;

import com.opensymphony.webwork.ServletActionContext;
import com.opensymphony.webwork.dispatcher.multipart.MultiPartRequestWrapper;
import com.opensymphony.xwork.ActionInvocation;
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;

/**
 *
 */
public class FileUploadInterceptor implements Interceptor {
    protected static final Log log = LogFactory.getLog(FileUploadInterceptor.class);

    protected String allowedTypes;
    protected String disallowedTypes;
    protected Long maximumSize;

    /**
     */
    public FileUploadInterceptor() {
        if (log.isDebugEnabled()) log.debug("new FileUploadInterceptor()");
    }

    /**
     */
    public void init() {
        if (log.isDebugEnabled()) log.debug("init()");
    }

    /**
     */
    public void destroy() {
        if (log.isDebugEnabled()) log.debug("destroy()");
    }

    /**
     * list of allowed mime-types, optional
     */
    public void setAllowedTypes(String allowedTypes) {
        this.allowedTypes = allowedTypes;
    }

    /**
     * list of diallowed mime-types, optional
     */
    public void setDisallowedTypes(String disallowedTypes) {
        this.disallowedTypes = disallowedTypes;
    }

    /**
     * maximum file Size, optional
     */
    public void setMaximumSize(Long maximumSize) {
        this.maximumSize = maximumSize;
    }

    /**
     *
     * TODO: i18n!
     */
    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();
        }
        MultiPartRequestWrapper multiWrapper = (MultiPartRequestWrapper) ServletActionContext.getRequest();
        if (multiWrapper.hasErrors()) {
            Collection errors = multiWrapper.getErrors();
            Iterator i = errors.iterator();
            while (i.hasNext()) {
                //how to get to addError() from here?
                log.error((String) i.next());
            }
        }

        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) {
                log.error("Error uploading: " + fileName);
            } else {
                if (acceptFile(file, contentType, inputName))
                    invocation.getInvocationContext().getParameters().put(inputName, file);
                // Do additional processing/logging...
            }
        }

        //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;
    }

    //overload this method to modify accept behaviour
    //TODO: addErrors?
    //TODO: i18n!
    protected boolean acceptFile(File file, String contentType, String inputName) {
        if (log.isDebugEnabled()) log.debug("checking" + inputName + " " + file.getName() + " " + file.length() + " " + contentType);
        if (maximumSize != null && maximumSize.longValue() < file.length())
            log.error("file is too long:" + inputName + " " + file.getName() + " " + file.length());
        else if (allowedTypes != null && allowedTypes.indexOf(contentType) < 0)
            log.error("Content-Type not allowed:" + inputName + " " + file.getName() + " " + contentType);
        else if (disallowedTypes != null && disallowedTypes.indexOf(contentType) >= 0)
            log.error("Content-Type disallowed:" + inputName + " " + file.getName() + " " + contentType);
        //somehow we need to set error messages here...
        else {
            if (log.isDebugEnabled()) log.debug("accepted");
            return true;
        }
        if (log.isDebugEnabled()) log.debug("not accepted");
        return false;
    }

}

Example Page code:
<form .... enctype="multipart/form-data">
    ....
    select user icon:
    <input type="file" name="picture">
<form>

Example Action code:
/**
     */
    protected File picture;

    public void setPicture(File picture) {
        this.picture = picture;
    }

    /**
     */
    public String execute() {
        if (picture != null && picture.isFile()) {
            final File target = new File("...");
            if (target.exists()) {
                if (log.isDebugEnabled()) log.debug("Removed previous picture version");
                target.delete();
            }
            picture.renameTo(target);
        }
    }

If this Interceptor considered generally useful - may be it will be incorporated into WW2 codebase?

分享到:
评论

相关推荐

    webWork2开发指南

    9. **配置管理**:WebWork2的配置文件采用XML格式,可灵活配置Action、Interceptor、结果视图等。此外,它还支持基于注解的配置方式,减少XML配置的繁琐。 10. **插件系统**:WebWork2拥有强大的插件体系,可以扩展...

    java私塾][Spring讲解+webwork2整合+webwork2整合全套

    根据提供的文件信息,我们可以推断出这是一篇关于Java私塾中的Spring框架讲解与WebWork2整合教程的文章。下面将围绕这些关键词展开详细的讲解。 ### Spring框架基础 #### Spring简介 Spring是一个开源框架,最初由...

    webwork2官方文档中文版

    WebWork2是一款基于Java的开源MVC(Model-View-Controller)框架,它为构建企业级Web应用程序提供了强大的支持。这个“webwork2官方文档中文版”是针对开发者的重要参考资料,帮助他们理解和掌握WebWork2的核心概念...

    webwork2中文教程

    在本教程中,你将学习如何配置WebWork2的XML配置文件,包括Action Mapping、Interceptor配置等。你还将了解如何创建和使用Action,以及如何实现视图的跳转。教程还将涵盖WebWork2与其他技术(如Spring、Hibernate)...

    webwork2中文文档

    1. **WebWork2基础**:介绍WebWork2的基本架构,包括Action、Interceptor、DispatcherServlet等核心组件的作用和工作原理。解释如何配置WebWork2项目,如web.xml和struts-config.xml文件的设置。 2. **Action与控制...

    Webwork2_guide

    4. **拦截器(Interceptor)**:Webwork2引入了拦截器机制,允许在Action执行前后插入自定义逻辑。拦截器可以用来处理如登录检查、日志记录、性能监控等功能,极大地增强了框架的灵活性。 5. **动作(Action)**:...

    WebWork2配置

    WebWork2是一款基于Java的轻量级MVC(Model-View-Controller)框架,它在Web应用程序开发中起到了核心架构的作用。WebWork2是Struts的替代品,它提供了更强大的功能、更好的性能以及更优雅的API。在这个“WebWork2...

    webwork2开发指南

    WebWork2是一款基于Java的MVC(Model-View-Controller)框架,用于构建Web应用程序。在Web开发领域,它提供了一种结构化和模块化的开发方式,帮助开发者更高效地组织代码并实现业务逻辑。本指南将深入探讨WebWork2的...

    webwork2实例源代码

    4. **Interceptor(拦截器)**:拦截器是WebWork2的一个重要特性,它们是可复用的代码片段,可以插入到Action执行流程中,实现如日志记录、权限检查、事务管理等功能。通过配置,可以灵活地调整拦截器链。 5. **...

    webwork2个人学习总结

    Webwork2是一个基于Java的MVC(模型-视图-控制器)框架,它在Web应用程序开发中提供了一种组织和管理代码的方式。以下是对Webwork2框架的学习总结: 1. **JAR包下载与项目配置**: - 开始学习Webwork2时,首先需要...

    Struts 2 技术详解:基于WebWork核心的MVC开发与实践

    WebWork的这些特性被集成到Struts 2中,使得Struts 2成为了一个高效且易用的MVC框架。 **Struts 2的生命周期**: 1. 用户发起HTTP请求。 2. Struts 2 框架接收到请求,解析请求参数。 3. 拦截器链开始执行,按照...

    Webwork2-Guide.rar_webwork2

    5. **Struts-config.xml**: 配置文件,定义Action、Interceptor、数据类型转换等设置,是Webwork2应用的核心配置。 二、Webwork2的工作流程 1. 用户发起HTTP请求到达Web服务器。 2. DispatcherServlet捕获请求,...

    struts2与webwork2

    在探讨Struts2与WebWork2的联系与区别的过程中,我们不得不提到它们的历史渊源以及在Java Web开发领域中的地位。Struts2框架实际上可以视为WebWork2框架的继承者,两者之间的关系紧密而复杂,下面将从多个角度深入...

    webwork2教程

    ### WebWork2 教程详解 #### 一、引言 WebWork2 是一款轻量级的 Java Web 开发框架,它遵循 MVC (Model-View-Controller) 设计模式,旨在简化 Web 应用程序的开发流程。通过本文档的学习,您将能够掌握 WebWork2 ...

    webwork2+velocity的登陆例子(无需改动)

    在WebWork2中,主要组件包括Action、Interceptor和Result。Action是业务逻辑的载体,Interceptor则用于在Action执行前后进行拦截处理,如权限验证、日志记录等。Result是Action执行后的结果,它定义了如何展示或跳转...

    Webwork2 开发指南

    1. **Webwork2框架基础**:Webwork2的核心概念包括动作(Action)、表单(Form)、结果(Result)和拦截器(Interceptor)。动作负责处理用户请求,表单用于封装表单数据,结果定义了动作执行后的跳转逻辑,而拦截器...

    webworkDemo.rar_webwork_webwork2

    3. **Interceptor(拦截器)**:拦截器是WebWork2的一个强大特性,它们可以在Action执行前后执行一些预处理或后处理操作,如验证、事务管理等。通过在struts-config.xml中配置拦截器栈,可以灵活控制流程。 4. **...

    Webwork2开发指南

    **Webwork2 开发指南** Webwork2 是一个基于Java的开源MVC(Model-View-Controller)框架,专门用于构建动态、交互式的Web应用程序。它提供了强大的数据绑定、动作控制、异常处理以及国际化等功能,使得开发者能够...

    WebWork2中文手册

    2. **强大的拦截器(Interceptor)机制**:拦截器是WebWork2的一大亮点,它们可以像过滤器一样在Action执行前后插入自定义逻辑,如权限检查、日志记录等。这极大地提高了代码的可复用性和模块化。 3. **Ognl...

Global site tag (gtag.js) - Google Analytics