This week's book giveaway is in the Other Open Source APIs forum. We're giving away four copies of Storm Applied and have Sean Allen, Peter Pathirana & Matthew Jankowski on-line! See this thread for details.
I've built an application that allow users to upload files via http and I've setup a method for them to receive feedback in the browser to monitor the upload progress. The method requires the upload handler servlet to throw the "showprogress.jsp" to the client with the Refresh header set to force a refresh to the servlet every 5 seconds - which in turn checks the progress in the upload thread, updates the appropriate session information, resets the Refresh header, and redirects back to the "showprogress.jsp" page.
I know there must be better ways to monitor the upload progress, but that is an issue for another time/thread. Everything works perfectly, except the refresh. The servlet redirects to the jsp on the first pass and shows the initial information (files, sizes, percentages) correctly, but the page never refreshes to the specified servlet URL. I am providing the fully qualified URL for the refresh (http://server/context/servlet). In fact, if I manually enter the servlet URL (the same one specified in the refresh header) into the browser while the upload is in progress I get back "showprogress.jsp" with the updated status information on the uploads. While trying to figure out this issue I've found that I cannot get this refresh to work under any circumstances.
This will not cause "page.jsp" to show http://www.google.com after 3 seconds. Clearly I'm misunderstanding this process at some point and I suspect it has to do with the sendRedirect mucking things up, but I don't know how else to get the servlet to feed the jsp to the browser.
I _could_ have the servlet completely generate/display the html for the "showprogress.jsp" as setting the Refresh header without specifying the URL does seem to work, but 1) that's less convenient for my current application setup and 2) this should really be working and I'd like to figure out what it is that I'm missing.
Any help is greatly appreciated, and thanks in advance! :-)
I thought that sendRedirect was the problem, but this doesn't answer my question. In fact what I seem to be doing from my perspective is saying, "Hey, response object, here is some header information. Now take that and load this jsp page."
Simply setting the Refresh header won't get my jsp loaded, but calling sendRedirect invalidates the Refresh header. Is there a way to set http headers in the response object and have them remain applicable when a jsp page is loaded into the browser?
Randall Nickerson wrote:but this doesn't answer my question.
A call to sendRedirect is simply a shortcut to setting the appropriate headers, and so what you are doing is sending conflicting headers. Apparently, the redirect headers take effect before any refresh headers (which makes sense and may be spelled out in the HTTP spec, but I'm not going to search for it.)
In fact what I seem to be doing from my perspective is saying, "Hey, response object, here is some header information. Now take that and load this jsp page."
Nope -- you're saying go North and South as the same time.
Is there a way to set http headers in the response object and have them remain applicable when a jsp page is loaded into the browser?
I'd recommend backing up and approaching the problem in a more conventional fashion than trying to find tricks.
For example, if all you want to do is to track progress, why aren't you exploring Ajax options?
Joined: Aug 23, 2010
Well, I was hoping to get a more direct answer to my original question. Indirectly I guess I can infer that you are saying there is not a way to have a servlet send a jsp to a browser and have that jsp automatically reload the servlet using headers.
For my own clarification then, any headers you set within the servlet apply only to the content going to the browser directly from that servlet (generally)? I understand that nothing is actually sent to the browser until the response is committed, I just assumed that you could set header/status information and then "commit" the response to the browser by having it load a jsp file. I guess that is where my understanding broke down.
I understand that there are other, better ways to do this - ajax, etc. - than the one I have described (as I stated in my original post). I was actually pointed to this method from a blog posting I found somewhere and it works fine, but I think they were posting the upload status from the servlet, not trying to use a jsp. Unfortunately I do not at this point have the time to re-engineer an ajax-based solution, so unless something springs to mind I'll have to shelve this for a later date...
Randall Nickerson wrote:Well, I was hoping to get a more direct answer to my original question. Indirectly I guess I can infer that you are saying there is not a way to have a servlet send a jsp to a browser and have that jsp automatically reload the servlet using headers.
Well, sure there is. You just didn't do that.
Your servlet didn't "send a JSP to a browser". It sent a response to the browser, telling it to redirect to a JSP. So the browser will automatically send a request for that JSP, and display its response.
Now you could have had that JSP include a "refresh" header, but you didn't. You're still stuck on the idea of having the original servlet tell the browser to do the refresh, which (as we already saw) isn't the way to do it.
Problem is, I think, you still don't have a clear idea of what's going back and forth between the browser and the server. And you're applying a mental model with fuzzy concepts like "send a JSP to a browser", which doesn't help. I found this a difficult thing to get rid of when I first started with web applications. You have to stop using fuzzy concepts to describe what's happening and start thinking of requests and responses.
+1... it's really important to understand what things like sendRedirect do to avoid issues like this. One easy way to get into is kind of detail is to use things like Firebug, or logging proxies, etc. to watch the actual traffic between client and server.