How to Invoke Servlets and JSPs with the RequestDispatcher
The RequestDispatcher allows your servlet to invoke other servlets, JSPs or static pages. You can either forward to them or only include their output.
Getting the RequestDispatcher
There are three ways to obtain a RequestDispatcher:
- ServletContext.getNamedDispatcher returns a dispatcher for a servlet with the specified name.
- ServletContext.getRequestDispatcher looks up a dispatcher that handles the given path. The path must start with '/' and is relative to the web application root. It can be located in '/WEB-INF/'. If the path contains a query (like '/path?param1=value'), those value will be available in the invoked servlet's request parameters.
- ServletRequest.getRequestDispatcher works like the method in ServletContext, but it also allows paths relative to the original request path.
Request Attributes
If a servlet's RequestDispatcher was obtained using one of the getRequestDispatcher methods (and not using getNamedDispatcher), the following attributes are available in the ServletRequest:
| When? | Name | Description |
|---|---|---|
| forward | javax.servlet.forward.request_uri | original request URI (see getRequestURI) |
| forward | javax.servlet.forward.context_path | original context path (see getContextPath) |
| forward | javax.servlet.forward.servlet_path | original context path (see getServletPath) |
| forward | javax.servlet.forward.path_info | original path info (see getPathInfo) |
| forward | javax.servlet.forward.query_string | original query string (see getQueryString) |
| include | javax.servlet.include.request_uri | included request URI (see getRequestURI) |
| include | javax.servlet.include.context_path | included context path (see getContextPath) |
| include | javax.servlet.include.servlet_path | included context path (see getServletPath) |
| include | javax.servlet.include.path_info | included path info (see getPathInfo) |
| include | javax.servlet.include.query_string | included query string (see getQueryString) |
Forwarding
Forwards are often useful if you need to return different pages depending on user input. This example displays a simple form in its GET method, and parses submitted values in its POST method. Depending on the input values, it will either forward to an error JSP or a result servlet (the JSP and result servlet are not shown here):
import javax.servlet.http.*;
public class SumServlet extends HttpServlet {
private void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException {
response.setContentType("text/html; charset=UTF-8");
response.setCharacterEncoding("UTF-8");
PrintWriter writer = response.getWriter();
writer.print("<html><head><title>Calculator</title></head><body>");
writer.print("<form method='POST'><input name='x'> + <input name='y'> ");
writer.print("<input type='submit' value='='></form>");
writer.print("</body></html>");
}
private void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException {
String x = request.getParameter("x");
String y = request.getParameter("y");
// find target
RequestDispatcher disp;
if (x != null && y != null && x.matches("[0-9]+") && y.matches("[0-9]+"))
disp = getServletContext().getNamedDispatcher("result-servlet"); // by servlet name
else
disp = request.getRequestDispatcher("/WEB-INF/jsps/error.jsp");
// forward to target
disp.forward(request, response);
}
}
Forward to Static Content
You can also forward to static files. Here is a much shorter implementation of the AmPmFileServlet shown above:
import javax.servlet.http.*;
// Servlet that sends one of two PNG images, depending on time of day
public class AmPmFileServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
// before or after noon? determine path to the right image in the WAR
boolean isPM = new GregorianCalendar().get(Calendar.AM_PM) == Calendar.PM;
String resName = "/WEB-INF/images/time" + (isPM ? "PM" : "AM") + ".png";
getServletContext().getRequestDispatcher(resName).forward(request, response);
}
}
Including Content
When including a servlet, JSP or static content, their output is written to including servlet's output, but any changes to the header will be discarded:
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
response.setContentType("text/html; charset=UTF-8");
response.setCharacterEncoding("UTF-8");
PrintWriter writer = response.getWriter();
request.getRequestDispatcher("header.jsp").include(request, response);
writer.println((new Date()).toString());
request.getRequestDispatcher("footer.jsp").include(request, response);
}
sendRedirect vs RequestDispatcher
The difference between a RequestDispatcher forward and the sendRedirect method is that with a forward, everything happens on the server-side. POST parameters will not be lost and the client will not notice that it is being forwarded.
With a redirect, the server tells the client to request the new URL, and thus the clients notices that it is being redirected. From the perspective of a web browser's user, the difference is that with a redirection she sees the new URL in the location bar. In many browsers going back to a page with redirection means that the user is being redirected again, effectively breaking the 'back' button.

