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 fromHttpServletResponse
andRequestDispatcher
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)
andServletRequest.getRequestDispatcher(String path)
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
.
- Get a servlet context instance from the servlet instace
ServletContext sc = this.getServletContext();
- 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");
- 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
method takes a string argument indicating the Name of the servlet known to the ServletContext.getNamedDispatcher
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