[ Team LiB ] Previous Section Next Section

Dispatching to Other Resources

The Servlet specification defines a mechanism for all servlet containers to facilitate the dispatch of requests from one Web component to other Web components such as JSP, servlets, or HTML pages. This can be achieved either directly or indirectly. In the indirect scenario, a Web component such as a servlet returns a page to the browser. This page contains an embedded URL (META REFRESH tag) that points to a different Web component. The browser then redirects the client to the other Web component. In a direct dispatch, a servlet might forward the request to another servlet or JSP for further processing, or might include the output of another servlet or JSP in the final output back to the requestor.

The Request Dispatcher

The RequestDispatcher interface in the javax.servlet package provides a mechanism for forwarding requests to other servlets and including responses from other servlets. The RequestDispatcher interface can be created using one of the following ways:

  • ServletContext.getRequestDispacher— Returns the dispatcher for a given path. The object returned acts as a wrapper for the Web component located at the specified path.

  • ServletContext.getNamedDispatcher— Returns the dispatcher identified by the given name. Servlets and other Web resources can be named using the Web application deployment descriptor (web.xml).

  • ServletRequest.getRequestDispatcher— Returns the dispatcher for a given path.

The difference between the first and the third options is that the specified path is relative to the current context root in the first option and is relative to the current servlet in the third option. When the specified path begins with a / in the third option, the path given is from the current context root.

The RequestDispatcher interface can either include another Web resource or forward the request to another Web resource using include() and forward(), respectively. The arguments to these methods are either ServletRequest and ServletResponse objects (which are passed to the service() and doXXX() methods) or subclasses of these objects, such as the HttpServletRequest and HttpServletResponse objects. Alternatively, request and response wrappers with embedded request and response objects, which are explained later, can be used to forward or include using the dispatcher.

Additionally, when the request dispatcher is created using the getRequestDispatcher() method, it allows for specifying parameters in the path. In our simple servlet example, requests can be forwarded to a JSP to generate the output for the client as in the following code snippet:


String path = "formatter.jsp?INPUT_STRING="+convertedString;
RequestDispatcher rd = ctx.getRequestDispachter(path);
rd.forward(request,response);

The parameters specified in the path when creating a request dispatcher override the parameters defined in the request object. In the earlier case, INPUT_STRING in the request object is overridden by the INPUT_STRING defined in the path.

The Include Method

When called on the request dispatcher, the include() method includes the response from another Web component via a servlet. This operation simulates a server-side include when the included resource is static like an HTML page. If the Web component is a servlet or a JSP, the included resource is executed and the output from it is included in the final response of the wrapping servlet to the client. The included servlet or JSP has complete control of the request along with the parameters, but access to the response object is limited. The included resource does not have the privilege to change or add to the header information; namely, it cannot add a cookie, change status, flush the buffer, and the like. The included resource can populate the response by using the ServletOutputStream or Writer that can be obtained from the response object. After that, control is returned to the original component, and it can add even more information to the response if need be.

In our simple servlet, the header information printed before the actual output containing the converted string can be printed using an included JSP or HTML page. Figure 14.6 describes the flow when output from another JSP/servlet is included into the response for a client request. As you can see, the invoked servlet has control over sending the response back to the client.

Figure 14.6. Include dispatching mechanism.

graphics/14fig06.gif

The Forward Method

The forward() method is used to transfer control from a servlet or JSP to another Web component. This method could be used in functions in which the initial processing is performed by a servlet and the output or some additional processing might be handled by a JSP or another servlet. After the second component is done, control does not go back to the first one. In our simple servlet, the main processing of the uppercase conversion can be done in the servlet and the response can be formatted with the help of JSP using the forward() method. This design provides a big benefit by separating the presentation and the processing logic; that is, it separates HTML code from pure Java code.


if (dto.getConfirmationNumber() != null) {
     errorDetected = true;
      req.setAttribute("ErrorMessage",
             "This user has not been confirmed.  Please respond to email sent.")
      ServletContext sc = getServletContext();
      RequestDispatcher rd = sc.getRequestDispatcher("/login.jsp");
      rd.forward(req, res);
}

In the previous Web application login servlet, the forward() method is invoked to redirect the user to the login JSP when the user tries to log in with an invalid credential. Figure 14.7 describes the flow when the forward dispatching mechanism is used. In this case, the response is sent directly from the forwarded servlet/JSP to the client.

Figure 14.7. Forward dispatching mechanism.

graphics/14fig07.gif

There are rules governing the use of forward() method:

  • After forwarding the request, the request URL points to the forwarded page. The original URL is lost after the forward is successful. But if this information is needed, the developer can leverage the set of methods provided by the ServletRequest and all other known sub-interfaces for retrieving and setting attribute values. The developer can use it to store customized request information. If the original URL is needed, it has to be stored as a attribute in the request before forwarding.

  • No output should be committed to the client before forwarding a request. If the servlet response has been flushed or committed, an IllegalStateException is thrown.

  • If the response buffer contains data, WebLogic Server clears the content before the request is forwarded.

  • Any attempts to retrieve the Writer or the OutputStream after a request forward in the caller component results in an IllegalStateException.

According to the Servlet specification 2.3, authentication is not required for a forwarded request. WebLogic Server provides a way to override this behavior by using the <check-auth-on-forward/> element. This element has to be added to the <container-descriptor> element of the WebLogic-specific deployment descriptor (weblogic.xml) as given here:


<container-descriptor>
        <check-auth-on-forward/>
</container-descriptor>
    [ Team LiB ] Previous Section Next Section