• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

HELP! Problems with Buffer/Response Committed

 
Ranch Hand
Posts: 585
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I have my page directive as:

but when I try to forward to another page it throws an exception:
java.lang.IllegalStateException: Response has already been committed
at org.apache.tomcat.facade.HttpServletResponseFacade.sendError(HttpServletResponseFacade.java:202)
at org.apache.tomcat.facade.HttpServletResponseFacade.sendRedirect(HttpServletResponseFacade.java:228)

What's going on here? I thought if I set the buffer to a large size and stopped it from auto-flushing that I'd be able to redirect but I can't!!
Please help!
Also, I have another problem if you can help:
I've set the error page as such (in web.xml):

but that error code gets thrown and it never goes to my error page. however, if I set "errorPage=error.html" in the page directive, it goes there on an error. why isn't the web.xml mapping it up?
thanks.
 
Sheriff
Posts: 67747
173
Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'd suggest rather than trying to find specious work-arounds for the problem, why not sit back and look at the structure of your page to determine why you feel the need to perform the forward AFTER some output has already been generated.
hth,
bear
 
Robert Paris
Ranch Hand
Posts: 585
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks for the completely not helpful comment. I am NOT WRITING anything anywhere. I have no out.println's and no <%= %> anywhere. I never print anything out. But I did discover the problem (and it's stupid in the servlet api if you ask me):
I call:
getServletConfig().getServletContext().getRequestDispatcher( "/FormHandle" ).include( request, response );
Where the servlet "/FormHandle" checks in a database for the info input and returns after setting a session and request attribute. Then, if the attribute's correct, I forward them to another page. I see no problem with the logic in that.
Problem is, after I include the servlet, it says my response is committed even though I NEVER touch the response object ANYWHERE.
Anyone know how i can fix this? What can/should I be doing?
 
Rancher
Posts: 13459
Android Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
MVC
Send the initial request to a processing servlet, allow the servlet to make all of the calls to gather the data and make it available on the request, then include or forward to the JSP to provide the view.
There may be a problem with the Server you are using sending the HTTP header prematurely even though you aren't sending any page content, but this is pretty unlikely. I think it is more likely you are letting accidental white space be output which is causing the response buffer to be filled and committed.
The other possibility is that 'include' calls can cause the buffer to be flushed even if you haven't requested that to happen. In effect, the getRequestDispatcher().include call causes the response to be comitted. Once again the MVC approach should fix it.
Hope you find this useful.
I agree with Bear though, concentrate on the error being thrown and not on mapping the 500 code. No idea why it doesn't manage that code correctly though..
Dave
[ February 03, 2003: Message edited by: David O'Meara ]
 
Robert Paris
Ranch Hand
Posts: 585
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
But David - MVC IS what I'm doing. Here's what happens:
1. The page registers some actions (my classes and api that I created)
2. It hands off to the form handler servlet which uses the form and the actions
3. The form handler delegates allactions to whatever servlet does that action (like a data processing servlet)
4. It hands the results back to the JSP
5. The JSP (the only thing that should be aware of what IT wants to do) then sees what the response is and decides where to send the user (i.e. with a forward).
Anyways, even if the form handler tried a forward, it wouldn't work either. Once you do a RequestDispatcher.include() you can no longer forward anywhere. And THAT is stupid. I don't understand that! It's basically forcing me to do everything on one page! So it says, make this page be the initiator, the setup and the processor as well as the view. Nothing else can control it, nor can it get info from other servlets and then send the user anywhere.
This really makes no sense from an MVC standpoint. (And before anyone goes telling me that people have been doing MVC with JSP/Servlets, I'll bet if I looked at it I'd see a ton of places where it's NOT MVC. I've talked to a ton of people who have said they were doing MVC - or "N-Tier" as the buzzword in the MS world is called - and it wasn't)
 
Bear Bibeault
Sheriff
Posts: 67747
173
Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

I am NOT WRITING anything anywhere.


Well, that's important info that wasn't included in your original post (search through this forum and you'll find dozens of posts where people try to forward after emitting reams of data...)
Apparently something is causing the response to commit. If you're not exlicitly performing output, it may be difficult to isolate.
One tactic could be to scan the java class created on behalf of your JSP to see if anything in your page is inadvertently turning into a output call prior to your forward.
Of course David's suggestion of separating processing from display is always a good one!
hth,
bear
 
Robert Paris
Ranch Hand
Posts: 585
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Well, I'm guessing from what I've read that the "include()" function considers whatever you're doing in there to be included in the response, so the moment you call include, it flushes the buffer to get ready for it (is there a way to stop this?). So is there an "execute()" function? I know that in the latest version of ASP (not ASP.net) they finally added a function like this to go along with include and forward/redirect. Execute merely executed some page or class on the ASP page's behalf but never wrote it into the response.
 
David O'Meara
Rancher
Posts: 13459
Android Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
see the syntax for the JSP include tag:
<jsp: include page="{ relativeURL | <%= expression %>}" flush="true" />
Using this tag you can specify flush="false" and it shouldn't flush the buffer before including the new file, but I haven't heard anything about its behaviour or stability (ie thats how it should behave, no guarantees on how it is actually done)
Submitting to a Servlet that doesn't output anything is still preferred.
That is, the request gets sent to the Servlet. The Servlet does the 'execute' stuff, then includes the JSP for display. The trick is making sure the Servlet is responsible for processing and not display and that the JSP is responsible for display and NOT processing.
 
Robert Paris
Ranch Hand
Posts: 585
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
OK, I created a solution for anyone needing one. To make include more like "execute", do this:
First create a class that implements HttpServletResponse and ServletResponse (I actually pass it the response object so it can implement some of the "get" methods only). Then pass THAT as the response object into include. Here's a class for you to get started:

Then, pass it like this:
getServletConfig().getServletContext().getRequestDispatcher( "/MyServlet" ).include( request, new EmptyResponse() );
That's it! You can of course go further and put an actual buffer in there too! then they can write to THAT response buffer (which normally is NOT allowed) and then you can extract it and add it to the real response in your JSP page. Yay!
 
Robert Paris
Ranch Hand
Posts: 585
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
ok, I take it back. I must have changed something else because now it's not working again. That makes no sense to me since I passed a fake response object, yet it still won't let me forward to another page! What's going on?
 
Robert Paris
Ranch Hand
Posts: 585
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
it allows me to include more than once (which it didn't before) when I use EmptyResponse, but when I try to forward, it says I already retrieved the OutputStream. Anyone know what's doing this and how I can stop it from getting the outputstream or printwriter?
 
Robert Paris
Ranch Hand
Posts: 585
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
please, anyone who can help me solve this - it's driving me nuts!
Why can't I call requestdispatcher.include with a fake response object, and then forward to another page with the real response object? It always says that I obtained the response outputstream or printwriter even though I never did either (although request dispatcher may have but I don't see how since I passed it a different response object!)
 
Ranch Hand
Posts: 64
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Robert, I had the same problem, did you try to look in the Servlet class generated by the container (in the /work directory). I bet you there are some out.write() calls.
 
Robert Paris
Ranch Hand
Posts: 585
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
you're probably right. Or maybe it sets headers? The thing is, I looked at tomcat's implementation of requestdispatcher and I'm thinking it can't be that because the only flsuhing/writing it does is on the response object I pass it. This is so frustrating. I really don't get why I can't execute a servlet without writing to the response? Doesn't it make sense from an MVC point to be able to have a servlet simply execute some data handling (or whatever) but have nothing to do with the response (i.e. the VIEW!!!)
 
Ranch Hand
Posts: 374
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
IMHO, there's generally little reason to manipulate things such as your buffer size manually. In fact, it's probably what's causing your issues. Setting the buffer size sets the buffer property on the out object, and setting it can only be done once. So by setting the buffer size, you are implicitly committing your response.
For reference:
http://java.sun.com/products/jsp/tags/11/syntaxref118.html
You should be able to do any number of includes, with or without associated controllers, without issue. If you don't write a single thing to your response, don't set any properties, etc etc, you can probably then forward. But if you're doing includes, there's probably little reason to also do a forward.
As an example, in Struts/Tiles you can associate a controller with a view and include the view result by referencing the controller. i.e. do an include of showUserInfo.do which forwards to userInfo.jsp and voila, the result of userInfo is included. You don't need to do the forward.
If you have a set of processes that need followed in order, forward your way through them rather than trying to include them. If you're trying to include the results of servlet1 and servlet2 before forwarding to sevlet3, instead try
servlet1 forward to servlet2 forward to servlet3.
This gives a much more loose coupling and allows each servlet to determine whether to continue the processing or redirect to an error page or handler.
 
Ranch Hand
Posts: 365
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yes, David is absolutely correct.
 
The only taste of success some people get is to take a bite out of you. Or this tiny ad:
a bit of art, as a gift, the permaculture playing cards
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic