问题
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?
回答1:
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
Jersey with Struts2
How to use Servlet in Struts2
Official Apache Documentation: web.xml
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
- Need to upload multiple files at once
and that can work with other upload-oriented frameworks with minor adjustments, like demonstrated in:
- Upload multiple files in Struts2 with Dropzone.js
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.
来源:https://stackoverflow.com/questions/28305919/what-is-eating-my-uploadfile-before-my-post-servlet-can-process-it