【问题标题】:File upload interceptor does not call setter methods文件上传拦截器不调用setter方法
【发布时间】:2014-05-22 12:42:29
【问题描述】:

我需要做非常基本的文件上传操作,但在我的情况下,文件上传拦截器不会调用 setter 方法。

我已经在 stackoverflow 上检查了类似问题 like this 的解决方案,但它们没有解决我的问题。

请告诉我我在代码中犯了什么错误。

动作类

public class ResultFileUploadAction extends ActionSupport {
    private File upload;
    private String uploadFileName;
    private String uploadContentType;
    private Logger logger = Logger.getRootLogger();

    @Override
    public String execute() throws Exception {
        logger.info("ResultFileUploadAction->execute");
        String destPath = "C:/work/";
        try {
            System.out.println("Src File name: " + upload);
            System.out.println("Dst File name: " + uploadFileName);
            File destFile = new File(destPath, uploadFileName);
            FileUtils.copyFile(upload, destFile);

        } catch (IOException e) {
            e.printStackTrace();
            return ERROR;
        }

        return super.execute();
    }

    public void setUpload(File upload) {
        this.upload = upload;
    }

    public void setUploadContentType(String uploadContentType) {
        this.uploadContentType = uploadContentType;
    }

    public void setUploadFileName(String uploadFileName) {
        this.uploadFileName = uploadFileName;
    }
}

Jsp 文件

<body>

    <s:form action="upload" method="post" enctype="multipart/form-data">
        <input type="file" name="upload" id="uploadfile" />
        <input type="submit" id="submit" />
    </s:form>
</body>

Struts.xml

<interceptors>
    <interceptor name="fileupload"
        class="org.apache.struts2.interceptor.FileUploadInterceptor"></interceptor>
    <interceptor name="servletConfig"
        class="org.apache.struts2.interceptor.ServletConfigInterceptor" />
    <interceptor name="authenticationinterceptor"
        class="interceptors.common.AuthenticationInterceptor"></interceptor>
    <interceptor-stack name="securestack">
        <interceptor-ref name="authenticationinterceptor"></interceptor-ref>
        <interceptor-ref name="servletConfig"></interceptor-ref>

    </interceptor-stack>
</interceptors>

<action name="upload" class="actions.result.ResultFileUploadAction"
    method="execute">
    <interceptor-ref name="securestack"></interceptor-ref>
    <interceptor-ref name="fileupload"></interceptor-ref>
    <result name="success" type="dispatcher">/AddResultBullk.jsp</result>
</action>

由于没有调用 setter,因此我在 execute() 中得到了 NPE

【问题讨论】:

  • AFAIK 如果没有常规参数拦截器,这将无法工作。通过剥离几乎所有框架的默认拦截器,您冒着消除很多功能的风险——一般来说,我不建议这样做。请使用更完整的拦截器堆栈仔细检查。
  • @DaveNewton 你是对的,fileupload 与 defaultstack 一起工作,但是 javadoc 中没有提到这个拦截器必须与默认堆栈中的一些(不知道是哪一个)拦截器一起使用。至少应该有一个注释。
  • 文件上传文档指出拦截器“添加参数”,这对我来说意味着它需要 params 拦截器。
  • 不使用拦截器上传,不起作用。还有stackoverflow.com/a/20071814/573032

标签: java file-upload struts2


【解决方案1】:

fileUpload 拦截器文档中所述:

它添加了以下参数,其中 [File Name] 是 HTML 表单上传的文件的名称。 [文件名,内容类型]

当使用拦截器堆栈时,总是有两种攻击计划:

  • 尝试非自定义堆栈
  • 除非您确切地知道为什么要这样做,以及要做什么,否则不要乱用堆栈。

此外,配置为几乎不使用拦截器的操作(如您的操作)几乎总是值得怀疑的,因为它们消除了大部分框架功能。尤其是参数是基本上每个基于表单的操作的关键。

【讨论】:

    【解决方案2】:

    当你想实现一个新的拦截器时,最好将它们添加到链的前面或后面的默认堆栈中,我在尝试添加一个拦截器进行身份验证并结束之前遇到了同样的问题通过以下练习,我将更新您的 代码提及我的想法:

    ...
    <interceptors>    
        <interceptor name="authenticationinterceptor" class="your.class.name" />
        <interceptor-stack name="securestack">
            <interceptor-ref name="authenticationinterceptor" />
            <interceptor-ref name="defaultStack" />
        </interceptor-stack>
    </interceptors>
    <!--
    Implicitly use securestack for all actions.
    -->
    <default-interceptor-ref name="securestack" />
    ....
    <!-- 
    and if you want some actions to pass from secureStack and use defaultStack
    (ex login page), you can state that explicitly, See:
    -->
    <action name="GetLoginPageAction" class="your.class.name">
        <interceptor-ref name="defaultStack" />
        ...
    </action>
    
    <!-- 
    for upload action you can use interceptor without define 
    it in the interceptors tag only in the action, 
    Note that you should explicitly use securestack below
    -->
    <action name="upload" class="actions.result.ResultFileUploadAction">
        <!-- You can remove the below refs because fileUpload is already 
             included in defaultStack that is included in the securestack 
             and securestack is default interceptor for all actions.
        <interceptor-ref name="securestack"/> 
        <interceptor-ref name="fileUpload"/>
        -->
        ...
    </action>
    

    希望这些笔记对你有所帮助。

    【讨论】:

    • 我也是这样做的。感谢您确认我的实施。
    猜你喜欢
    • 2012-08-18
    • 2015-08-14
    • 2014-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多