FileUpload,Struts2,FileUploaderInterceptor中没有文件

时间:2019-04-11 10:54:13

标签: java spring-boot struts2 portlet

在Portlet模式下,有一个正常工作的Struts2 portlet环境,在该环境中我无法使Struts fileUpload正常工作。

我可以看到

  • 文件被上传到服务器,在临时空间中创建。
  • 原始请求中包含一个多部分请求,文件名 和文件内容,在其中输入Struts类。
  • 我可以触发最大尺寸响应,这是Struts中设置的默认值。
  • 已触发FileUploadInterceptor,但在雅加达 MultipartRequest没有文件。原来之间的某个地方 请求和Jakarta包装器文件丢失。

我在精简的Spring boot 2应用程序中尝试过相同的方法,与主项目中发生的问题相同。 遵循代码

https://struts.apache.org/core-developers/file-upload.html

用于JSP和操作类。 Portlet已创建,流程有效,但操作中没有文件。

带有额外Pom的标准Sping Boot 2:

<dependency>
    <groupId>org.apache.struts</groupId>
    <artifactId>struts2-spring-plugin</artifactId>
    <version>2.5.20</version>
</dependency>
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.2</version>
</dependency>
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.4</version>
</dependency>

Struts.xml

<package name="uploadtest" extends="struts-portlet-default" namespace="/uploadtest">

    <action name="uploadtestPrepare" class="bouvet.no.fileuploadtest.action.FileUploadSubmitAction">
        <result name="success">/WEB-INF/struts2/test/fileUpload.jsp</result>
    </action>
    <action name="uploadTestSubmit" class="bouvet.no.fileuploadtest.action.FileUploadSubmitAction">
        <result name="success">/WEB-INF/struts2/test/fileUpload.jsp</result>
    </action>
</package>

和表格

<s:form action="uploadTestSubmit" method="post" enctype="multipart/form-data">
    FileName: <s:property value="%{filename}"/>
    <s:file name="upload" label="File" />
    <s:submit/>
</s:form>

二传手

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

这是Portlet模式下的错误,还是我缺少关键的依赖项,组件,版本?替代方法?

在图像中,JSR168调度程序中的一个断点存在该文件。在服务器之后运行的第一个代码。 breakpoint in JSR168 dispatcher

1 个答案:

答案 0 :(得分:0)

在这种情况下,解决方案是退后一步,查看请求中存在的内容。 实际上,Portlet运行所在的CMS在上传到达Portlet环境之前会负责上载。我发现的jakarta包装器是由CMS创建的,但它在portlet范围之外。

解决方案:

   public String intercept(ActionInvocation invocation) throws Exception {
        final ActionContext context = invocation.getInvocationContext();

        Object action = invocation.getAction();
        try {
            if (action instanceof FileUploadAware) {
                HttpServletRequest request = (HttpServletRequest) context.get(HTTP_REQUEST);
//                if (request instanceof MultipartRequestWrapper) {
                    File file = (File) request.getAttribute("upload");
                    ((FileUploadAware) action).setFile(file);

//                }
            }
        }catch (Exception e){
            LOG.error("Exception? {}", e);
        }finally {
            return invocation.invoke();
        }

不是最终解决方案,而是概念,它是一种拦截器,可在请求中找到一个上载属性,并将其置于FileUploadAware操作中。该属性是CMS截获并创建的本地临时文件。 这对我有用,对于此CMS是特殊的解决方案还是对Portlet通用?不知道。