在我的 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
,如
Jersey with Struts2
How to use Servlet in Struts2
然后输入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 方法。
我在我的网页上使用 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
,如
Jersey with Struts2
How to use Servlet in Struts2
然后输入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 方法。