在我的 POST servlet 可以处理它之前,'eating' 我的 uploadFile 是什么?

What is 'eating' my uploadFile before my POST servlet can process it?

我在我的网页上使用 Infragistics IgniteUI igUpload 将文件上传到我们的 Apache Tomcat 服务器,在上传文件时,我无法在我的 servlet 代码中访问它们。也许这里有人知道发生了什么事。

当 igUpload 通过 Ajax 发送文件时,我看到一个格式很好的 POST 请求 Headers :

Accept  text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding gzip, deflate
Accept-Language en-US,en;q=0.5
Content-Length  24804
Content-Type    multipart/form-data;  boundary=---------------------------91823184012919
Cookie  JSESSIONID=BB4D29EEA9C703CA529EA48E74413A72
Host    localhost:8080
Referer http://localhost:8080/MyApp.html
User-Agent  Mozilla/5.0 (Windows NT 6.1; WOW64; rv:29.0) Gecko/20100101 Firefox/29.0

Post 部分中的用户文件 'header' :

-----------------------------91823184012919 Content-Disposition: form-data;
 name="uploadDoc_0__frm_if"; filename="UsersFile.xls" Content-Type: application/vnd.ms-excel

我的 servlet 然后被调用,但是当我使用它时(来自 FileUpload 文档的代码片段):

                DiskFileItemFactory factory = new DiskFileItemFactory();
                // Configure a repository (to ensure a secure temp location is used)
                ServletContext servletContext = this.getServletConfig().getServletContext();
                File repository = (File) servletContext.getAttribute("javax.servlet.context.tempdir");                   
                factory.setRepository(repository);                                       
                // Create a new file upload handler                   
                ServletFileUpload upload = new ServletFileUpload(factory);                                       
                // Parse the request                   
                List<FileItem> items = upload.parseRequest(request);

"items" 列表总是空的。但是,在 Eclipse 调试中,我可以看到深埋在请求 object 中的一个指向用户文件的 DiskFileItem,该文件存储在一个临时目录中。从这个 post File upload with ServletFileUpload's parseRequest? 看来 struts2 正在我的 servlet 有机会获取文件之前。所以我调查了 struts2 FileUploadInterceptor 并没有找到太多。我想用我自己的拦截器覆盖它,但它永远不会被调用。我得到了 FileUpload 源,所以我可以设置断点,并且在此 fileUpload 过程中从未调用它。我看到执行的第一个代码是我的 servlet,此时文件已经处理完毕。

那么 eating/uploading/storing 我的文件实际上是什么,我该如何停止它或使用它以便我可以实际使用上传的文件?

感谢您的任何见解。

================================编辑============ ======================

我在下面的@Andrea Ligios 回答中为我的 servlet 添加了 struts.xml 常量,但没有用。然后我检查了 web.xml 文件,它确实有那些过滤行,除了它是

org.apache.struts2.dispatcher.FilterDispatcher

但是我注意到我的 struts 版本是 2.3.4,它应该具有您在答案中列出的较新名称。我将过滤器名称更改为您指定的新名称,现在可以使用了!

不过看来我必须手工做很多工作。我没有使用 built-in 的原因是因为我使用的是此处描述的 Infragistics jQuery igUpload 控件 http://www.igniteui.com/file-upload/overview and here http://help.infragistics.com/Doc/jQuery/2014.2/CLR4.0?page=igUpload_igUpload.html 。使用此控件时,它会发送 POST 消息,如我在问题中所述。我猜它是为与 ASP.NET MVC Helper 一起工作而设计的,我什至不知道那是什么。 Infragistics IgniteUI 在其文档中从未提及 struts。鉴于我正在使用 igUpload,您能否提出任何其他建议来简化此过程?

如果您正在使用 Struts2,您可能会在 web.xml 中进行此设置:

<filter>
    <filter-name>struts2</filter-name>
    <filter-class>
        org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
    </filter-class>
</filter>

<filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

由于url-pattern是/*,这意味着每个请求都会被StrutsPrepareAndExecuteFilter拦截(通常称为Filter Dispatcher,这也是旧的过滤器名称,在 2.1.8 之前的 Struts 个版本中。

如果你调用一个动作,那就完美了。如果您调用 servlet、web 服务或其他东西,这是有问题的,因为 Struts 过滤器应该 运行 仅用于操作。

要排除特定 url(或特定模式)被过滤器拦截,您需要在 struts.xml 中使用常量 struts.action.excludePattern,如

然后输入struts.xml

<constant name="struts.action.excludePattern" value="/YourServlet"/>

它应该可以工作。


在这一点上,我很想知道你为什么使用 Struts2 而没有利用强大的内置文件上传功能,这在

中有解释
  • Need to upload multiple files at once

并且只需稍作调整即可与其他面向上传的框架一起使用,如以下所示:

  • Upload multiple files in Struts2 with Dropzone.js

我不知道您使用的是什么插件,但在您的情况下,我看到的第一个(可能也是唯一一个)问题是发送的参数名称:

uploadDoc_0__frm_if

应该是无编号的,它仍然需要在你的变量名中混合 CamelCase / Snake_case 方法。