Tuesday, March 22, 2011

Chapter 18: Using a RequestDispatcher

The request dispatcher is an important tool for any J2EE developer who is building a web application that involves multiple JSPs and Servlets. In this chapter, we are going to look at it in detail.

So, lets get started!!!

The RequestDispatcher

The RequestDispatcher is a useful tool. You can perform programmatic server-side includes or route the whole request to another servlet or JSP with a forward. The purpose of the request dispatcher is to direct control from one jsp/servlet to another so that the application can take a course of action that would help complete the current user request.

Getting the Request Dispatcher

The request dispatcher can be obtained in 3 ways. They are:
1. ServletContext.getRequestDispatcher(java.lang.String)
2. ServletContext.getNamedDispatcher(java.lang.String)
3. ServletRequest.getRequestDispatcher(java.lang.String)

The first two ways are getting the dispatcher from the servlet context. Either way of invoking returns a RequestDispatcher object that acts as a wrapper for the named servlet.

Whereas, the third way uses the servlet request. You can use a relative pathname here whereas with the servletcontext we need to use the absolute pathname.

Exam Trivia:
We need to be careful while using the paths. If the path begins with a “/”, it is interpreted as relative to the current context root. You will get a null if the servlet container cannot return a RequestDispatcher. Be sure to use the correct path name and to spot inconsistencies in the code in case the exam puts one in front of you.

Purpose of the RequestDispatcher:

The RequestDispatcher object can be used to forward a request to the resource or to include output from the resource in a response. The specification allows the resource to be dynamic or static. If it is dynamic, such as a servlet, the container will invoke that servlet, and then take the output and include it. If it is static, such as a text file, then the container will include the text as it is.

Lets now look at some sample code as to how the RequestDispatcher can be used.

Sample Code 1:

public void doGet (HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
try {
getServletConfig()
.getServletContext()
.getRequestDispatcher("/SomeExample")
.forward(request, response);
} catch (Exception ex) {
ex.printStackTrace ();
}
}

The above code can be used to forward the control to the SomeExample servlet and include the contents of its output as part of this requests response back to the browser.

Sample Code 2:

RequestDispatcher dispatcher =
getServletContext().getRequestDispatcher(path);
if (dispatcher == null)
{
out.println(path + " not available");
return;
} else
{
dispatcher.include(request, response);
}

You can also include contents from a static page or another servlet in your response. The above code is how you can do it.

Did you notice the difference in the above 2 examples?

If you did not, just scroll up and see the code again. In example 1 I had used forward whereas in example 2, include is used. There are a few characteristics of these two methods.
1. The ServletRequest’s path elements and parameters remain unchanged from the caller’s
2. The included servlet cannot set headers
3. The servlet cannot change the response status code
4. The best way to send information from the calling servlet to the called servlet is using a query string or a better way would be to use the setAttribute() to set values into the request object and use it in the target servlet.
5. And finally, there is also a matter of timing that we need to consider. You can call an include anytime, but the forward has to be called before the response is committed. Otherwise you will end up getting an IllegalStateException.

Regarding the forward method, one reason you may want to use it is so you can dedicate a servlet as the controller. In this way, the controller can filter, preprocess requests, and manage the transaction. The gotcha here is once a servlet forwards a request, it loses control. The controller has no capability to regain access directly. You can create an architecture where requests are returned (forwarded back by a slave servlet), but the native functionality isn't helpful for this.

There is another problem which you need to remember for the exam. When you use the forward method, the URL in the address bar doesn't change. The client loses path information when it receives a forwarded request. That means all relative URLs in the HTML become invalid. Your browser will consider the links broken. Sometimes this doesn't matter, but when it does, you can use sendRedirect() instead.

Exam Trivia:
ServletContext.getRequestDispatcher()— This method uses absolute paths.
ServletRequest.getRequestDispatcher(String path)— The path may be relative, but cannot extend outside current servlet context.
ServletRequest.getNamedDispatcher(String name)— This name is the name of the servlet for which a dispatcher is requested, and is in the web.xml file

Previous Chapter: Chapter 17 - Servlet Lifecycle

Next Chapter: Chapter 18 - Listeners & Interfaces in Web Context

1 comment:

  1. Hi

    I read this post two times.

    I like it so much, please try to keep posting.

    Let me introduce other material that may be good for our community.

    Source: Dispatcher interview questions

    Best regards
    Henry

    ReplyDelete

© 2013 by www.inheritingjava.blogspot.com. All rights reserved. No part of this blog or its contents may be reproduced or transmitted in any form or by any means, electronic, mechanical, photocopying, recording, or otherwise, without prior written permission of the Author.

ShareThis

Google+ Followers

Followers