Tuesday, March 21, 2006

AJAX Struts File Upload Progress Meter

** This Post is a work in progress, and is still being worked on, it hasn't been edited yet, and may contain errors, use at your own risk **

Over the course of the last year or so I have been hearing a lot about AJAX, and how cool it is, and what neat stuff you can do with it. At first I wasn't too impressed, mostly because I have heard it all before. It wasn't until I saw
google maps that I realized how cool it was. I have been itching to use Ajax ever since.

My first attempt at AJAX was using the Google Maps API to add a map to the search results page on CampRate.com. It is fairly simple, the search allows the visitor to search for campgrounds given a zip code and a search radius. I search the CampRate.com database and return the campgrounds in the area, and I then add Site Markers onto the google map so that it is easier to see where the campgrounds are located. This was fairly easy to setup given the fact that Google opened up their API.




Once I finished the Google Map hack, I was looking for something else to do. After looking around for a little while I thought of the perfect thing to AJAXify. On CampRate.com we allow Campground Owners to upload images of their campgrounds to the site, and campers are also allowed to upload images of their camping trips for everyone to see. The interface for this is very simple, it is just a regular File browse box and a submit button, once they upload the image, the browse box goes away and a thumbnail of the image is inserted. This is a very basic and a very late 90's way of doing things. What a prefect thing to AJAXify.

Once I knew what I was going to work on, I needed to figure out how I could improve on the design. After a couple of revisions I came up with the new design and layout. One of the features that I thought would be good to use AJAX for, is a progress bar for showing the status of the upload.

Here is what the new upload page looks like, this is where I would like to add a progress bar.



Progress Bar.
Before I started coding for the progress bar, I decided to search around to see if anyone else had used a progress bar before. I found a bunch of examples, PHP, Ruby, and a good one using Java + DWR. I decided to look at the Java + DWR example since I was already using Java and DWR on CampRate.com. The Java + DWR example was a great start, the only problem was that it didn't use Struts and once the file was uploaded it changed pages. There were some comments associated with the article that mentioned how to get it to work with Struts, so I decided to take the source code from the article and play with it and see if I could get it to work with Struts.

What I wanted to change in the example.
  • Get the example to work with struts
  • get the file to upload to a selected directory
  • show the status of the file in the progress meter
  • when the file is uploaded don't leave the page, stay on the same page (no redirect or refresh).
What I did.
  • I downloaded the war file with source code from the article
  • refactored the project directory
  • changed the build script
  • setup struts, log4j
  • added logging statements for easier debugging
All of the new struts code that I added was put into a new package net.kencochrane so that you can easily see what is was originally there, and what was added in order to get struts to work with the original Code.


Struts Changes
  • Added the struts libs to the lib dir in the project
  • added the XML files to the config directory
  • changed web.xml so that it works with struts
  • created some actions, and form

Code Changes
  • Added a MultipartRequestHandler
  • added struts actions to handle all requests.
  • The example now actually stores the uploaded files to a temp directory.
  • Added a new package net.kencochrane

Uploading a file without leaving the page
I looked around to find a way to upload the files without leaving the page, but from what I could find, I guess you can't do this with javascript because of security reasons. The most common way to do this was to use an iFrame and use this iFrame to hold the upload form, and when the form is submitted the form gets posted like normal, and using some tricks with javascript you can make it look like the file is uploaded without ever leaving the page.

I changed the index.jsp file to include an iFrame, the iFrame holds the upload form. Using javascript I was able to make it looks like the files are being uploaded without leaving the page.

Here is what the new pages look like, the first image looks like the original form, the only difference is that the page is now using an iFrame to hold the upload form.



File upload in progress, it displays the progress bar until it is complete, and then the bar goes away and is replaced with a status message.


The file is finished,
progress bar is hidden, and the status message tells you the file status.



What is left to do
  • add better error checking
  • Check for file being uploaded that is too large.

Now What
Now that I have the example working the way I want it (with struts, DWR, and having the file uploaded without leaving the page.) I can work on adding this code to CampRate.com.

The more that I think about it, I could also use this on PopcornMonsters.com as well, we allow people to add images for movies, and actors to the site, but the interface is very ugly, once I get the code written for CampRate.com I could easily spend the time and get the same code to work on PopcornMonsters.com, that would make the whole adding images experience so much better.

Special Thanks to Pierre-Alexandre Losson for writing the original Article and for posting his code for everyone to use.

Download the code from this post for AJAX Struts File Upload Progress Meter.

I will update this post with some completed pictures once I finish up with all of the code. Feel free to post comments.

Ken Cochrane
http://KenCochrane.net


46 Comments:

At 2:03 AM, Anonymous Anonymous said...

Hi Ken,

Thanks for your post (and reference).

Pierre

 
At 6:40 AM, Anonymous Anonymous said...

A real nice code sample to accomplish the fileupload using struts.
Loads of Thanks to you and the original author too.

S P Vijay
Neev Technologies
www.neevtech.com

 
At 4:05 AM, Anonymous Anonymous said...

great article, thanks! is it possible to adapt that method to realize a progress bar for struts that holds the user until a page is completely loaded..?

regards
bernd

 
At 5:17 PM, Anonymous Anonymous said...

It work for me when the server run on my machine. But when I deploy my application on a server the getUploadInfo() in UploadMonitor is called only 1 time at the beginning. Do you know why ?

 
At 5:17 PM, Anonymous Anonymous said...

It work for me when the server run on my machine. But when I deploy my application on a server the getUploadInfo() in UploadMonitor is called only 1 time at the beginning. Do you know why ?

 
At 4:00 AM, Anonymous Anonymous said...

hi ken, thanks.
but is there an easier example. without any progress meter, etc. i only need the code for uploading files , nothing else.
greetings

 
At 7:05 AM, Blogger Ken Cochrane said...

mamue,

Do you need code to just upload using struts? or to upload using ajax + struts?

Here is a lin to a website that shows you a simple example on how to upload a file using struts..

http://www.roseindia.net/struts/strutsfileupload.shtml

 
At 3:49 AM, Anonymous Anonymous said...

hi ken,
thanks for your reply. i implemented the code in my web-project. it works so far, but when i try to enter your index.jsp through an html:form (e.g. for authentication) like - html:form action="login.do" - i receive an HTTP 404 error ("Invalid path /showUploadForm.do was requested"). I don't have problems with a normal link like - html:link href="login.do". do you know why? greetings

 
At 2:28 PM, Anonymous Anonymous said...

Ken,
It was cool to pick up your code, thanks a lot. Almost everything works fine except for the progress bar not changing when the file is loading it remains at 0% for some reason. I am not sure if it has to do with the upload.css, I tried using it or using just the inline styling both did not work.

2. Is there a good way to handle if a timeout occurs, as of now the Iframe gives a page not found if that happens, I want it to send the error to the parent page and that page handle the error gracefully. Just let me know the best way to handle such errors when you use Iframes.

thanks
Sashi

 
At 2:50 AM, Anonymous Anonymous said...

Hi,

quite good solution. But I guess it will eat a lot of memory. Could you please provide some stats about memory consumption? We've tried Xupload upload progress bar http://www.sibsoft.net/xupload.html and looks like their way quite good. It's actually regular upload and just track the status of uploaded file. There also other ways of doing that and there are several other uploads exists. Not sure how they will work with Java environment. Anyway, let us know about memory. Thanks.
Thanks.

 
At 12:40 PM, Anonymous Anonymous said...

If you are going to go with XUpload, you might as well try out the script that I wrote. The server side scripts borrow heavily from other sources (check the files for info), but I totally rewrote the JavaScript because I was very unhappy with all the other freeware upload scripts. You can use this in your projects for absolutely free.

 
At 8:33 AM, Anonymous Anonymous said...

You can consider using XUpload on your pages. Non AJAX upload progress bar which does not refresh progress bar window. Here's link: http://www.sibsoft.net/xupload.html

 
At 6:06 AM, Anonymous Anonymous said...

thanks!

 
At 3:57 PM, Anonymous Anonymous said...

Thanks Ken, I modified your example to work with our multipartrequesthandler.

Shay Logan
www.shaylogan.com

 
At 2:43 PM, Anonymous Anonymous said...

Great. I've been looking for such a script for weeks now. I've tried a few, but could never get them to work... Now im gonna try this one :)

 
At 5:28 AM, Anonymous Anonymous said...

Hi Ken,

I deployed AjaxUpload2.war to weblogic 9.2.
When i access the page using url:
http://localhost:7001/AjaxUpload2/index.jsp and browse a file and click begin upload...I just get the ....upload in progress: 0% and file name disappears from text field.Nothing happens in the progress bar.

Thanks And Regards
Raju

 
At 5:45 AM, Anonymous Anonymous said...

Hi Ken,

Its related to my earlier post of not seeing any activity in the progress bar.I think this happens if file size is too small.But when i uploaded file some bigger file say some 10MB for example it showed the progress but was getting stuck at say 90% or at 100% and not showing the upload success status.One more question was where does it upload the file?
Please ignore my earlier post.

Regards and thanks
Raju

 
At 7:57 AM, Anonymous Anonymous said...

Hi Ken,
Please ignore both the earlier posts from me.I saw the log,actually the path for the uploaded file was S:\temp\upload in HomeAction Class so it was just sort of hanging without any error unable to find the folder.

Sorry for that.

Thanks a lot for this great sample application,will try and build upon this.

Thanks a lot
Raju

 
At 11:57 PM, Anonymous Anonymous said...

Hi,

I have used File upload with my existing application and it works fine. but now i am using Struts 2.0 and I am facing problem in using your ExtendedMultipartRequestHandler Class.As we are not having to Struts 2.0 Struts config file.

Please provide some guideline to use File upload functionality with Struts 2.0 or if possible then provide us new source which is implemented using struts 2.0.

 
At 2:16 AM, Blogger Chetan Patil said...

Hi,

Does anybody knows, how to upload file using ajax + struts?

Please help.

 
At 5:12 AM, Anonymous Anonymous said...

Hi! I've been reading your blog from the beginning..Thank you for your wonderful work! Keep up the good work.

 
At 3:51 PM, Blogger AnujsDen said...

Hi Ken,
When i try to upload a very big file say 700 Mb then it gives http 500 error on web page and following error on console:
<2007-04-03 12:32:05,578> [ERROR] (@) org.apache.struts.actions.DispatchAction - Dispatch[/upload] to method 'doUpload'
returned an exception
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.apache.struts.actions.DispatchAction.dispatchMethod(DispatchAction.java:276)
at org.apache.struts.actions.DispatchAction.execute(DispatchAction.java:196)
at org.apache.struts.actions.MappingDispatchAction.execute(MappingDispatchAction.java:171)
at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:421)
at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:226)
at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1164)
at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:415)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:214)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:825)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:738)
at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:526)
at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
at java.lang.Thread.run(Thread.java:595)
Caused by: java.lang.OutOfMemoryError: Java heap space

PLEASE SUGGEST.

Thanks
Anuj

 
At 4:03 PM, Blogger Ken Cochrane said...

Anuj,

You are running out of memory, (look at last line of stack trace) "Caused by: java.lang.OutOfMemoryError: Java heap space"

You will need to give more memory to tomcat, you can do this by populating the CATALINA_OPTS values in your catalina.sh script look up "Tomcat Out of Memory" for more info.

I haven't tested it for anything this big, so you might have to tweak the code a little to use less memory.

Sorry I couldn't be more help.

 
At 6:28 PM, Blogger AnujsDen said...

Hi Ken,

I fixed the issue cos that was JVM memory error.Actually that time i was trying to upload 100MB file, now this time i tried with over 300 MB file and it seems to break. find below is the error from the console.
<2007-04-03 15:21:49,265> [DEBUG] (@) be.telio.mediastore.ui.upload.MonitoredDiskFileItemFactory - inside MonitoredDisk
FileItemFactory constructor (listener)
<2007-04-03 15:21:49,281> [DEBUG] (@) net.kencochrane.action.HomeAction - Inside home:doUpload
<2007-04-03 15:21:49,281> [DEBUG] (@) net.kencochrane.action.HomeAction - uploadForm = [UploadForm]
file1= null
file2= null
file3= null
file4= null
[/ UploadForm]

<2007-04-03 15:21:49,281> [DEBUG] (@) net.kencochrane.action.HomeAction - uploadDir = c:/temp/upload/
<2007-04-03 15:21:49,281> [ERROR] (@) net.kencochrane.action.HomeAction - error = java.lang.NullPointerException
java.lang.NullPointerException
at net.kencochrane.action.HomeAction.doUpload(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.apache.struts.actions.DispatchAction.dispatchMethod(DispatchAction.java:276)
at org.apache.struts.actions.DispatchAction.execute(DispatchAction.java:196)
at org.apache.struts.actions.MappingDispatchAction.execute(MappingDispatchAction.java:171)
at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:421)
at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:226)
at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1164)
at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:415)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:214)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:825)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:738)
at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:526)
at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
at java.lang.Thread.run(Thread.java:595)
<2007-04-03 15:21:49,281> [DEBUG] (@) net.kencochrane.action.HomeAction - Leaving home:doUpload
<2007-04-03 15:21:52,781> [INFO ] (@) uk.ltd.getahead.dwr.impl.ExecuteQuery - Exec[0]: UploadMonitor.getUploadInfo()
<2007-04-03 15:21:52,781> [DEBUG] (@) uk.ltd.getahead.dwr.impl.ExecuteQuery - --Object created, not stored. Call param
s () id=3379_1175638912734. Using (XHR,POST)
<2007-04-03 15:21:52,781> [DEBUG] (@) be.telio.mediastore.ui.upload.UploadMonitor - inside getUploadInfo()
<2007-04-03 15:21:52,781> [DEBUG] (@) be.telio.mediastore.ui.upload.UploadMonitor - [getUploadInfo] - got the req
<2007-04-03 15:21:52,796> [DEBUG] (@) be.telio.mediastore.ui.upload.UploadMonitor - [getUploadInfo] - return uploadInfo

<2007-04-03 15:21:52,796> [DEBUG] (@) uk.ltd.getahead.dwr.impl.DefaultExecProcessor - Returning: id[3379_1175638912734]
assign[s0] xhr[true]
<2007-04-03 15:21:52,796> [DEBUG] (@) uk.ltd.getahead.dwr.impl.DefaultExecProcessor - var s0={};var s1=0;s0.bytesRead=s
1;
var s2=0;s0.elapsedTime=s2;var s3=0;s0.fileIndex=s3;var s4=false;s0.inProgress=s4;var s5="done";s0.status=s5;var s6=0;s0
.totalSize=s6;

DWREngine._handleResponse('3379_1175638912734', s0);

Please Suggest.

Thanks
Anuj

 
At 3:51 PM, Blogger AnujsDen said...

Hi Ken,

I have spring framework, but i am failing to integrate this application within it. Please suggest how to configure DWR in spring. I have gone through some links like this one http://bram.jteam.nl/index.php/2007/01/31/spring-dwr-ajax-made-easy/#comment-21076
but all effort going in vain.

Please help.

Thanks
Anuj

 
At 11:17 AM, Blogger Fabien said...

How could I add a limit file size ?

 
At 10:54 AM, Blogger pedro.i.alcocer.jr said...

Thanks for the research. While it took me a good two days; I was able to successfully integrate the file upload progress bar into my struts project whichs uploads to a database rather then a folder. I had to make some adjustments because I am using tiles and regular action classes but it's kicking ass.

The customers will like it as they would get impatient and think the upload wasn't working for large files.

Thanks again.

 
At 1:27 PM, Blogger pedro.i.alcocer.jr said...

After reading this article, I was influenced enough to do a write on why to use Ajax with DWR. Here ya go and thanks again.

Check it out here!

 
At 1:30 PM, Blogger pedro.i.alcocer.jr said...

After reading this article, I was motivated to do a write up on AJAX through DWR. Check it out Here

Thanks

 
At 7:17 PM, Blogger EscapeArtist said...

I'm using with tomcat
(5.5.12) and common-fileupload (1.2) and I have this multi-upload
screen(ajax+java=my own) that works great from my intranet but when testing it from outside is not. I observed the following:

1. when I initiate an upload, it seems that the whole upload happens as a result of the form post instead of being progressively. I test from a place that has a proxy and my tomcat instance is fronted by an apache that handles the static content (coupled with mod_jk). What's really happening. Shouldn't the upload happen progressively via the proxy ? Is the file firstly uploaded to the proxy and from there to my site as one chunk ? Why this is not happening from my local box. I had other people complaining about this as well so it's not only my location. From my intranet works as it should - flawless.

2.If I initiate two concurrent uploads only the last one prevails and I get always an exception on the first one... This also works just fine from my local intranet. I assume both are related with each other.

2007-07-23 11:53:27,358 [TP-Processor11]: ERROR org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValv
e.java:253) - Servlet.service() for
org.apache.commons.fileupload.FileUploadBase$IOFileUploadException:
Processing of multipart/form-data request failed. Stream ended unexpectedly
at
org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase
.java:359)
at
org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase
.java:302)
at
org.apache.struts.upload.CommonsMultipartRequestHandler.handleRequest(Co
mmonsMultipartRequestHandler.java:185)
at
org.apache.struts.util.RequestUtils.populate(RequestUtils.java:405)
at
org.apache.struts.action.RequestProcessor.processPopulate(RequestProcess
or.java:818)
at
org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:
194)
at
org.apache.struts.action.ActionServlet.process(ActionServlet.java:1913)
at
org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:449)
at
com.goodmedia.framework.core.servlet.FrameworkActionServlet.doGet(Framew
orkActionServlet.java:119)
at
com.goodmedia.framework.core.servlet.FrameworkActionServlet.doPost(Frame
workActionServlet.java:131)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
at
com.goodmedia.framework.core.servlet.FrameworkActionServlet.service(Fram
eworkActionServlet.java:91)
at
com.gsi.core.servlet.GSIActionServlet.service(GSIActionServlet.java:128)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Applica
tionFilterChain.java:252)
at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilt
erChain.java:173)
at org.ajaxanywhere.AAFilter.doFilter(AAFilter.java:46)
at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilt
erChain.java:173)
at com.goodmedia.trim.TrimFilter.doFilter(TrimFilter.java:72)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Applica
tionFilterChain.java:202)
at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilt
erChain.java:173)
at
com.goodmedia.framework.core.servlet.UserManagerUtilsFilter.doFilter(Use
rManagerUtilsFilter.java:105)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Applica
tionFilterChain.java:202)
at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilt
erChain.java:173)
at
org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(Filt
erChainProxy.java:292)
at
org.acegisecurity.intercept.web.FilterSecurityInterceptor.invoke(FilterS
ecurityInterceptor.java:108)
at
org.acegisecurity.intercept.web.SecurityEnforcementFilter.doFilter(Secur
ityEnforcementFilter.java:197)
at
org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(Filt
erChainProxy.java:303)
at
org.acegisecurity.providers.anonymous.AnonymousProcessingFilter.doFilter
(AnonymousProcessingFilter.java:143)
at
org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(Filt
erChainProxy.java:303)
at
org.acegisecurity.ui.AbstractProcessingFilter.doFilter(AbstractProcessin
gFilter.java:246)
at
org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(Filt
erChainProxy.java:303)
at
org.acegisecurity.context.HttpSessionContextIntegrationFilter.doFilter(H
ttpSessionContextIntegrationFilter.java:220)
at
org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(Filt
erChainProxy.java:303)
at
org.acegisecurity.util.FilterChainProxy.doFilter(FilterChainProxy.java:1
73)
at
org.acegisecurity.util.FilterToBeanProxy.doFilter(FilterToBeanProxy.java
:120)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Applica
tionFilterChain.java:202)
at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilt
erChain.java:173)
at
com.goodmedia.framework.core.servlet.RequestUtilsFilter.doFilter(Request
UtilsFilter.java:96)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Applica
tionFilterChain.java:202)
at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilt
erChain.java:173)
at
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValv
e.java:213)
at
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValv
e.java:178)
at
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java
:126)
at
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java
:105)
at
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.
java:107)
at
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:1
48)
at
org.apache.jk.server.JkCoyoteHandler.invoke(JkCoyoteHandler.java:307)
at
org.apache.jk.common.HandlerRequest.invoke(HandlerRequest.java:385)
at
org.apache.jk.common.ChannelSocket.invoke(ChannelSocket.java:748)
at
org.apache.jk.common.ChannelSocket.processConnection(ChannelSocket.java:
678)
at
org.apache.jk.common.SocketConnection.runIt(ChannelSocket.java:871)
at
org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool
.java:684)
at java.lang.Thread.run(Thread.java:595)
Caused by:
org.apache.commons.fileupload.MultipartStream$MalformedStreamException:
Stream ended unexpectedly
at
org.apache.commons.fileupload.MultipartStream$ItemInputStream.makeAvaila
ble(MultipartStream.java:964)
at
org.apache.commons.fileupload.MultipartStream$ItemInputStream.read(Multi
partStream.java:887)
at java.io.InputStream.read(InputStream.java:89)
at
org.apache.commons.fileupload.util.Streams.copy(Streams.java:94)
at
org.apache.commons.fileupload.util.Streams.copy(Streams.java:64)
at
org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase
.java:354)
... 60 more

theqmaster at gmail dot com

 
At 6:24 PM, Anonymous Anonymous said...

Ken,

Would you be able to tell, why after parsing the request in the ExtendedMultipartRequestHandler, the text parameter doesn't hold the actual value. Instead it holds some bogus value. I selecting the destination field in the form. After form submission, this destination field in the request passed to handleRequest of EMRH is changed to bogus value. Also, when I try to retreive destination value as request.getParameter, null value is returned. Any suggestion, what's going on?

 
At 4:33 PM, Anonymous Anonymous said...

Looks like there is a bug in EMRH itself. Text parameters in request object is either corrupted or gets lost in EMRH.

 
At 11:51 AM, Anonymous Anonymous said...

hi ken, thanks for your precious post.
I'm tring to make a port for struts 1.0.2 and i have some problem.
the controller element in struts-config.xml is not allowed.
do u have any suggestion to solve this problem?
tnx

 
At 11:58 PM, Anonymous Anonymous said...

Hi Ken,

Thanks a lot.

It helped me a lot.

 
At 3:51 PM, Anonymous Anonymous said...

This is not working well in Mozila firefox.

Progress bar stops sometime at 77% or 95% . File uploads properly.

 
At 7:47 PM, Anonymous Anonymous said...

Hi Ken, all:

thanks for the great work, works like a charm no problem. I added some code to handle 10 files, does anyone know why nested:file ... does not show up directly unless you try to highlight from up donw with I.E or scroll with the middle button with fire fox.

Here is what I added to uploadForm.jsp and I added the necessary code to the homeAction.java etc, it works in term of functionality, but i don't see all the browse input button unless i do move the mouse somehow.

nested:file styleId="file5" property="file5" styleClass="default"
....
etc up to 10

So I can only see up to 6 and the "begin upload" button is hidden unless I scroll down, anyone know how I can fix this.

Sorry am new to struts and this staff.

thanks a bunch

 
At 1:38 AM, Anonymous Anonymous said...

no worries I figure it out it's the iframe scroll doing that.

cheers

 
At 1:31 AM, Anonymous Anonymous said...

Hi, Ken,
Thanks for your sharing.
However, it seems have a problem when uploading a large file
(in my case, about 20M), the AJAX action seems to be blocked (i.e., the progress bar is not updated) until the file actually uploaded to the server. (jsp solution works fine for the same file)
what may be the problem?

 
At 10:18 PM, Anonymous Anonymous said...

Great article.. i love ajax..ajax is available in: phpbb2, IPB, e107, basic java script, and flash script. Generally the maker of ajax does not make it for all of these but there are people that modify it to work with the listed systems.

 
At 6:26 AM, Anonymous Anonymous said...

Hi ken,
I'm working on struts..I'm facing problem while running your code
The problem is in Controller
when i upload file Its giving error in log file are as follows:
Nov 20, 2008 4:35:47 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet action threw exception
java.lang.NullPointerException
at net.kencochrane.upload.ExtendedMultiPartRequestHandler.handleRequest(ExtendedMultiPartRequestHandler.java:176)
at org.apache.struts.util.RequestUtils.populate(RequestUtils.java:442)
at org.apache.struts.action.RequestProcessor.processPopulate(RequestProcessor.java:816)
at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:203)
at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1196)
at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:432)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:710)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:390)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Thread.java:619)

 
At 6:31 AM, Blogger vaishali Dolas said...

Hi ken,
I'm working on struts.
when i'm running application in ExtendedMultiPartRequestHandler file its giving exception..Please help me out

 
At 3:06 AM, Blogger KiVi said...

I am unable to download the zip file... can you upload it as a war file?

 
At 10:50 AM, Blogger Ken Cochrane said...

@Kishore

Why can't you download the zip file?

This code is pretty old, and I only have the code in the zip file. Sorry.

 
At 10:59 AM, Anonymous Kodshah said...

it is not working in safari kindly check it and let me know how it will work or what is configuration required for it

 
At 9:52 AM, Anonymous Anonymous said...

Hi Ken,

I have a question. Did you use fileUpload interceptor in the struts definition?

I would like to know how to implement it on this because right now we are using this for file uploads but we need to know how much the user has already uploaded.

Please help.

Thank you.

 
At 9:54 AM, Anonymous Anonymous said...

Hi Ken,

I am looking for a way to monitor the file upload progress of users through the struts file upload interceptor.

Is the one you modified capable of doing this?

Thank you.

 

Post a Comment

<< Home