• Post Reply Bookmark Topic Watch Topic
  • New Topic

What actually happens when RequestDispatcher.forward() is called  RSS feed

 
Steve Cohen
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You think you know JSP and then something like this happens!

Let's say you have a jsp page, which, when it is compiled, checks the session, and if not finding everything it expects there, gets a RequestDispatcher and uses it to forward somewhere else. However, there is java code following the call to forward() in the compiled version of the JSP. Does that continue to execute? Why not, and if not, what eventually stops it from executing?

I have some java code on a JSP, running under JBoss, of which the following is a reasonably good pseudocode represenation:

if (session is not any good) {
getServletConfig().getServletContext().getRequestDispatcher(logoutPage).forward(request,response);
}
session.setAttribute(someAttribute, someValue);

This creates an IllegalStateException on the setAttribute(). The precise error message is "Cannot create a session after the response has been committed."

The forward happens, causing a commit, but the java continues to execute, and tries to set the session attribute afterward and an exception is thrown.

So the forward is certainly NOT a drop-dead stop order on the further java code on the compiled page. So, then, exactly what IS going on here?

A valid fix to my code is something like this.
if (session is good) {
session.setAttribute(someAttribute, someValue);
} else {
getServletConfig().getServletContext().getRequestDispatcher(logoutPage).forward(request,response);
}

But this raises as many questions as it answers.

I have several pages that are similar to this one, but with the difference that there is MORE java code between the session check and the setting of the session attribute. Somewhere during this code, the java stops executing because the setAttribute never happens and there is no error.

Can anyone give a good explanation for this? I feel like I'm on very squishy ground here and I don't like feeling this way.
 
David O'Meara
Rancher
Posts: 13459
Android Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Personally I feel the problem is more to do with general page design than the forward method. I'll outline the way I tend to do things and the merits.

Firstly you have to follow the MVC architecture and separate models (ie data) and views (ie display). It is important to gather and prepare all data before trying to display any of it - or even before deciding who will provide the display. The key rule is that you shouldn't send anything back to the client till you feel ready to send it all.

This allows you to detect and manage anticipated and unanticipated problems cleanly. Since you haven't sent anything to the client the response cannot be comitted and you can still send any response you want. A kind of side-issue is to be certain that the design of your code prevents you from accidentally including or forwarding to multiple views. It may just be best to follow .include, .forward or .sendRedirect calls with a return;

The second point is in the design of the view. It's more of a guideline than a rule, and takes a bit of experience to get it right. The best 'view' is one that performs no processing or parsing, and just drops data straight into place on the screen. In practice loops, conditional code and output formatting make this harder. The closer you get to this the better, and the less problems you'll have, ever.

The last pointer is to get used to defensive coding with your data, since the most likely errors in your view will be unchecked exceptions, and 90% of those will be NullPointers. If you manage null values before hand this is no longer an issue either.

Basically you end up with a design where anything which occurs in the controller and has to with the data can be managed cleanly, and you've prevented almost any problems in the view.

It's taken a long to get here, but my answer is: sort things out so you can forward if you need to, and allow yourself to make this decision before anything gets sent to the client.

Dave
 
Steve Cohen
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for the advice. Would that we were using an MVC architecture. Unfortunately, we inherited something that is anything but. Maybe we get to refactor it. If we're lucky.

I had considered your idea of a return after the forward statement. I think that might be the cleanest alternative in the mess I'm in. It resolves a lot of the ambiguity.

On a theoretical note, though, what DOES happen on a forward? I assume that the container is somehow killing the thread that was generating the forwarding page. Would it then be the case that the behavior in this case is platform dependent? That would make sense. The server where this is happening runs jboss-3.2.1 on solaris. My development box runs jboss-3.2.5 on Windows 2K.
 
Jessica Sant
Sheriff
Posts: 4313
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm going to move this to the JSP forum where the topic fits a bit better.

So please continue the conversation there. Thanks!
 
Bear Bibeault
Author and ninkuma
Marshal
Posts: 65833
134
IntelliJ IDE Java jQuery Mac Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The specific mechanics of what actually happens is indeed up to the implementing container. The general mechanics could be summed up as "when this resource is complete (returns), here's the next resource to process before you return the response to the requestor".

You certainly seem to "get it" when it comes to David's architectural suggestions, but for anyone else reading this thread, read David's advice carefully and take it to heart.

I will also add that the use of the JSTL and EL on-page helps to eliminate even the minimal Java that would otherwise have been necessary to iterate, conditionalize and perform other dynamic actions on behalf of the view.

Especially under JSP 2.0, scriptless pages can be a reality and are a joy to behold (and create, and maintain, and refactor, and... oh, you get it).
 
David O'Meara
Rancher
Posts: 13459
Android Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Steve Cohen:
On a theoretical note, though, what DOES happen on a forward? I assume that the container is somehow killing the thread that was generating the forwarding page. Would it then be the case that the behavior in this case is platform dependent? That would make sense. The server where this is happening runs jboss-3.2.1 on solaris. My development box runs jboss-3.2.5 on Windows 2K.


No, as Bear says, the first piece of code runs through to the end, then the code for the forwarded or included sections gets to run. If the initial piece of code does not stop cleanly (typically by using a return; after the forward call) it is possible to accidentally have multiple forward, sendRedirect and include statements which all conflict.

This is why it's an even better idea to get your processing done as the first step, then decide what the next step is all at once rather than scattering forwards and includes throughout your code.

Dave
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!