Servlet Redirections

Whether building a new Web application or adding some new pages in the existing Web application, it is always required to forward the processing of a request to another Servlet, or to include the output of another servlet in the response. This can be achieved by two ways of servlet redirections.

Following are the methods of Servlet redirections:

  • sendRedirect method from HttpServletResponse and
  • RequestDispatcher interface.

sendRedirect method

This method redirects the response back to the client’s browser with the status code. The container decides whether it can handle the request or not. If the container identifies that the request can’t be handled then the browser will normally interpret this response by initiating a new request to the redirect URL given in the response. This method works only in the browser.

Example:

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class RedirectDemo extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        String un = request.getParameter("username");

        if (un.equals("coder")) {
            response.sendRedirect("SuccessServlet");
        } else {
            response.sendRedirect("FailedServlet");
        }
    }
    
}

Because the browser issues a completely new request, any objects stored as request attributes before the redirect occurs will be lost. Hence, the requested data is lost.

RequestDispatcher interface

The RequestDispatcher allows the dynamic inclusion of web components either by including in the current component or by forwarding to another web component. It takes requests from the client and sends them to other resources available on the server. Resources could be any Servlet, HTML, JSP, or other. A RequestDispatcher has the following two primary methods.

  • Include: This is for including the response of another program in the currrent request.
  • Forward: This is forwarding the request of the current program to another one.

An object implementing the RequestDispatcher interface may be obtained via the following methods:

  • ServletContext.getRequetDispatcher(String path)
  • ServletRequest.getRequestDispatcher(String path) and
  • ServletContext.getNamedDispatcher(String path)

RequestDispatcher with ServletContext

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. Following are the steps of getting an instance of RequestDispatcher.

  1. Get a servlet context instance from the servlet instace

ServletContext sc = this.getServletContext();

  1. Get a request dispatcher from the servlet context instance specifying the page-relative or application-relative path of the target JSP or Servlet as input to the getRequestDispatcher() method.

RequestDispatcher rd = sc.getRequestDispatcher("/SuccessServlet");

  1. Invoke the include() or forward() method of the request dispatcher specifying the HTTP request and response objects as parameters.

rd.forward(request, response);

or

rd.include(request, response);

Example:

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class RedirectDemo extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        String un = request.getParameter("username");

        ServletContext sc = this.getServletContext();
        
        if (un.equals("coder")) {
            RequestDispatcher rd = sc.getRequestDispatcher("/SuccessServlet");
            rd.forward(request, response);
        } else {
            response.sendRedirect("FailedServlet");
        }
    }
    
}

ServletContext method requires an absolute URL that must begin with / (Forward Slash). If you try to use the URL without / then it will show an exception.

Let’s see an example:

ServletContext sc = this.getServletContext();
RequestDispatcher rd = sc.getRequestDispatcher("SuccessServlet");
rd.forward(request, response);

At the runtime, this code will throw an exception:

HTTP Status 500 – Internal Server Error
Type Exception Report

Message Path [SuccessServlet] does not start with a "/" character

Description The server encountered an unexpected condition that prevented it from fulfilling the request.

Exception

java.lang.IllegalArgumentException: Path [SuccessServlet] does not start with a "/" character
	com.codersathi.servlet.RedirectDemo.doGet(RedirectDemo.java:23)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:655)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
	org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
Note The full stack trace of the root cause is available in the server logs.

RequestDispatcher with ServletRequest

The ServletRequest.getRequestDispatcher method allows relative paths that are relative to the path of the current request (not relative to the root of the ServletContext). It is provided in the ServletRequest interface. The behavior of this method is similar to the method of the same name in the ServletContext.

Example:

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class RedirectDemo extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        String un = request.getParameter("username");
       
        if (un.equals("coder")) {
            RequestDispatcher rd = request.getRequestDispatcher("SuccessServlet");
            rd.forward(request, response);
        } else {
            response.sendRedirect("./FailedServlet");
        }
    }
    
}

In the above example, we haven’t started a URL Pattern value with / (Forward Slash). Because it does not make mandatory to add it, unlike in the ServletContext. Hence, it still works even we add /.

ServletContext.getNamedDispatcher(String servletName)

The ServletContext.getNamedDispatcher method takes a string argument indicating the Name of the servlet known to the ServletContext. If a servlet is found, it is wrapped with a RequestDispatcher object and the object is returned. If not servlet is found with the given name then the method will return null.

When RequestDispatcher object is null then it will throw NullPointerException. The detailed message is:

java.lang.NullPointerException: Cannot invoke "javax.servlet.RequestDispatcher.forward(javax.servlet.ServletRequest, javax.servlet.ServletResponse)" because "rd" is null

Example:

Let’s say we have defined a servlet on the web.xml file shown below.

<servlet>
      <servlet-name>redirectDemo</servlet-name>
      <servlet-class>com.codersathi.servlet.RedirectDemo</servlet-class>
 </servlet>

Now we can give the Servlet name in ServletContext.getNamedDispatcher(String servletName):

RequestDispatcher rd = sc.getNamedDispatcher("RedirectDemo"); // Here the RedirectDemo is the servlet name not URL Pattern.
rd.forward(request, response);

Conclusion

In this post, we learned the various ways of Servlet Redirection in detail. In RequestDispatcher there are two methods forward and include. When to choose between them is discussed in another post Servlet Request Dispatcher method forward vs include

Sharing Is Caring:
Subscribe
Notify of
2 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments