什么是在我的POST servlet处理它之前“吃"我的uploadFile? [英] What is 'eating' my uploadFile before my POST servlet can process it?

查看:104
本文介绍了什么是在我的POST servlet处理它之前“吃"我的uploadFile?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

当igUpload通过Ajax发送文件时,我看到带有标题的格式正确的POST请求:

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

,并且在发布"部分中的用户文件带有以下标头":

-----------------------------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);

项目"列表始终为空.但是,在Eclipse调试中,我可以看到在Request对象中埋有一个DiskFileItem,该DiskFileItem指向用户文件,该文件存储在一个临时目录中.从这篇文章使用ServletFileUpload的parseRequest上传文件?我的servlet有机会.因此,我调查了struts2 FileUploadInterceptor并没有发现太多内容.我用自己的拦截器覆盖了它,但是它从未被调用过.我得到了FileUpload源,因此可以设置断点,并且在此FileUpload过程中从不调用它.我看到执行的第一个代码是我的servlet,到那时该文件已经被处理.

那到底是什么在吞噬/上传/存储我的文件?如何停止它或使用它,这样我才能真正使用上载的文件?

感谢您的见解.

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

我从下面的@Andrea Ligios答案中为我的servlet添加了struts.xml常量,但是该常量不起作用.然后,我检查了web.xml文件,它的DID除了那些过滤器行以外,还有其他过滤行

org.apache.struts2.dispatcher.FilterDispatcher

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

但是看来我必须手工做很多工作.我不使用内置控件的原因是因为我使用的是Infragistics jQuery igUpload控件,此处所述 http://www.igniteui.com/file-upload/overview 和此处解决方案

如果使用的是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模式是/*,这意味着每个请求都被StrutsPrepareAndExecuteFilter(在2.1.8之前的Struts版本中通常称为Filter Dispatcher,它也是旧的过滤器名称)拦截.

如果您叫一个动作,那是完美的.如果您调用servlet,Web服务或其他服务,则会出现问题,因为Struts Filter应该仅针对操作运行.

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

所述.

然后放入struts.xml

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

它应该工作.


在这一点上,我很想知道您为什么在不利用强大的内置文件上传功能的情况下使用Struts2,这在

中有解释

,并且可以与其他面向上传的框架进行细微调整,例如:

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

 uploadDoc_0__frm_if
 

应该没有编号,并且仍然需要在变量名中使用CamelCase/Snake_case混合方法.

I'm using Infragistics IgniteUI igUpload on my webpage to upload files to our Apache Tomcat server, and while the files are uploaded, I can't get access to them in my servlet code. Maybe someone here has an idea of whats happening.

When igUpload sends the file through Ajax, I see a nicely formed POST request with 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

and the users file in the Post section with this 'header' :

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

My servlet then gets invoked, but when I use this (code snippet from FileUpload doc):

                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);

The "items" list is ALWAYS empty. However, in Eclipse debug I can SEE buried deep in the Request object a DiskFileItem that points to the users file, which was stored in a temporary directory. From this post File upload with ServletFileUpload's parseRequest? it seems like struts2 is taking the file before my servlet gets a chance to. So I looked into struts2 FileUploadInterceptor and didn't find much. I tied to overwrite it with my own Interceptor and it never gets called. I got the FileUpload source so I could set breakpoints and it is never called during this fileUpload process. The first code I see executing is my servlet and by that point the file is already processed.

So WHAT is actually eating/uploading/storing my file, and how do I either stop it, or work with it so I can actually use the file that was uploaded?

Thanks for any insight.

================================EDIT ==================================

I added the struts.xml constant from @Andrea Ligios answer below for my servlet and that didn't work. Then I checked web.xml file and it DID have those filter lines except it was

org.apache.struts2.dispatcher.FilterDispatcher

However I noticed that my struts version is 2.3.4, which should have the NEWER name you listed in your answer. I changed the filter name to the new one you specified and now it works!

However it appears I have to do a lot of work by hand. The reason I'm not using the built-in is because I'm using Infragistics jQuery igUpload control described here http://www.igniteui.com/file-upload/overview and here http://help.infragistics.com/Doc/jQuery/2014.2/CLR4.0?page=igUpload_igUpload.html . When using this control it sends the POST msg as I described in my question. I guess its made to work with ASP.NET MVC Helper and I don't even know what that is. Infragistics IgniteUI never mentions struts in their documentation. Given that I'm using igUpload, can you make any other suggestions for making this easier?

解决方案

If you are using Struts2, you will probably have this setting in 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>

Since the url-pattern is /*, it means that every request is intercepted by the StrutsPrepareAndExecuteFilter (usually called Filter Dispatcher, that was also the old filter name, in Struts versions before 2.1.8).

If you call an action, this is perfect. If you call a servlet, a web-service, or something else, this is problematic, because Struts Filter should run for actions only.

To exclude a particular url (or a particular pattern) from being intercepted by the filter, you need to use the constant struts.action.excludePattern in struts.xml, as described in

Then put in struts.xml

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

And it should work.


At this point, I'm curious to know why are you using Struts2 without exploiting the great inbuilt File Upload functionality, that is explained in

and that can work with other upload-oriented frameworks with minor adjustments, like demonstrated in:

I don't know the plugin you're using, but in your case the first (and probably only) problem I see is the name of the parameter sent out:

uploadDoc_0__frm_if

should be unnumbered, and it'll still need a mixed CamelCase / Snake_case approach in your variable name.

这篇关于什么是在我的POST servlet处理它之前“吃"我的uploadFile?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆