© Copyright Marcus Green 2007

Objective 5) The RequestDispatcher mechanism

3.5) Describe the RequestDispatcher mechanism; write servlet code to create a request dispatcher; write servlet code to forward or include the target resource; and identify and describe the additional request-scoped attributes provided by the container to the target resource.

What is a RequestDispatcher?

The RequestDispatcher allows the dynamic inclusion of web components either by including in the current component or by forwarding to another web component. A typical use is to include a standard menu in all pages. This reduces the amount of duplication of content and if the menu has to change, only one file needs editing.

A RequestDispatcher object can be obtained by calling the getRequestDispatcher method of the ServletContext object. An instance of ServletContext can be obtained by calling the getServletContext method of the HttpServlet class. As a servlet extends the HttpServlet class the getServletContext method is available through the this object as in the following example

/**
 * Demonstrating the RequestDispatcher
 * mechanism
 * Marcus Green Summer 2006
 **/
import java.io.*;
import java.net.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class RequestDispatch extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    ServletContext sc = this.getServletContext();
    RequestDispatcher dis = sc.getRequestDispatcher("/menu.jsp");
      if (dis != null){
          dis.include(request, response);
      }
      PrintWriter out = response.getWriter();
      out.print("Output after the content of menu.jsp");
   }
}

The text in the call to out.print will appear in the output page, as processing of the current servlet continues after the call to include. If you cange the call from include to

dis.forward(request, response);

This exact same code will work, but the call to out.print will never appear in the output page as processing is transferred to the resource that is forwarded to. Note that the resource that is included or forwarded can be a static html page, but of course that precludes any processing within that page.

The ServletRequest object also supports the getRequestDispatcher method. Thus a JSP page could include code as follows.

<%
RequestDispatcher rd = request.getRequestDispatcher("menu.jsp");
rd.forward(request,response);
%>

Note that the parameter to getRequestDispatcher does not begin with a forward slash /. The key difference between the getRequestDispatcher of ServletRequest and ServletContext is that with ServletRequest you can use a relative URL.


ServletRequest.getRequestDispatcher can take a relative URL. ServletContext.getRequestDispatcher cannot

If you create a request dispatcher as follows

protected void doGet(HttpServletRequest request, HttpServletResponse
response) throws ServletException, IOException { ServletContext sc = this.getServletContext(); /*This code will generate a runtime error *because of the lack of a forward slash before *the getRequestDispatcher parameter */ RequestDispatcher dis = sc.getRequestDispatcher("menu.jsp"); if (dis != null){ dis.include(request, response); } }

At runtime it will produce an error, which on my Tomcat setup was as follows.

java.lang.IllegalArgumentException: Path menu.jsp does not start with a "/" character
com.examulator.ReqD.doGet(ReqD.java:13)
javax.servlet.http.HttpServlet.service(HttpServlet.java:689)
javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:362)

Request Dispatcher vs Redirect

The redirect mechanism as covered in topic 1.3 is superficially similar to the request dispatcher mechanism. The important difference is that the dispatcher system is purely server side and invisible to the web browser. The re-direct mechanism by contrast is an instruction to the web browser. Often this is not important, but you need to know this for the purpose of the exam.

RequestDispatcher == server side, redirect == client side

Object Visibility

Included or forwarded objects do not share Java variables with the originating resource, but they do share attributes. Thus if you include the following code

  request.setAttribute("username","Marcus");

Within the doGet method, it will be possible to retrieve the value of that attribute with a call to

request.getAttribute(“username”);

It would be possible to share data via the session Object (via a call to getSession method explained in section 4.1). However this would break the general principle of giving data the narrowest visibility, as any data stored in the session would still be visible after the Servlet finished processing.

JSP supports the equivalent action via the jsp:include, jsp:forward, and jsp:param. Actions which are described in section 8.2


Other resources

The RequestDispatcher API docs
http://java.sun.com/j2ee/1.4/docs/api/javax/servlet/RequestDispatcher.html

Invoking other web resources from the Sun tutorial
http://java.sun.com/j2ee/1.4/docs/tutorial/doc/Servlets9.html

This objective according to Mikalai Zaikin
http://java.boot.by/wcd-guide/ch03s05.html