Engineering Full Stack Apps with Java and JavaScript
All calls to other resources in a web application should go through the container. RequestDispatcher is a mechanism provided by the container for that purpose. Container will give us an implementation of the RequestDispatcher interface and we can use it to delegate control to other resources in the application.
You can obtain RequestDispatcher object from
ServletContext object through the
getRequestDispatcher(String urlPathToResource) or
getNamedDispatcher(String servletLogicalName) methods,
ServletRequest object through the
getRequestDispatcher(String urlPathToResource) method.
Note: The getRequestDispatcher method of ServletContext can accept only a context relative url starting with forward slash (/) whereas the ServletRequest version can accept servlet relative url without a forward slash (/) as well.
RequestDispatcher has two methods
‘void forward(ServletRequest request, ServletResponse response)’
to forward the ServletRequest to the specified resource in RD completely delegating the response and
‘void include(ServletRequest request, ServletResponse response)’
to include the runtime evaluation of the specified resource in RD and execution continues in the current servlet.
Please refer to the demo to understand these rules better:
An included servlet's contents are added to the current servlets output.
Included servlets contents are added to the current servlets output. If we call more includes, data from all includes will be included in the response unless any of the include servlet or even the parent servlet do a commit. If a commit is made, no exception is thrown for subsequent calls to include. However, any data after commit (including from the included servlet and parent servlet) are ignored and are not sent to client.
Whenever you make a request to forward, all data already in the response buffer is cleared and not sent in response.
You should not forward after a commit. When you forward, the response is commited by container before returning back, and hence you cannot forward again.
If you do any commit before forward even unknowingly (e.g. from inside the include servlet), you will still get the exception.
Similarly, if you try to forward after a call to out.flush() or out.close(), you will get the same exception.
Any data after commit (including from the included servlet) are ignored and are not sent.
Even if you try to write more contents to the initial servlet's out after a commit (after a forward, or after a call to out.flush() or out.close()), the data is discarded.
If we have already called getWriter in the FirstServlet, calling getOutputStream will give an exception: java.lang.IllegalStateException: getWriter() has already been called for this response.
[Recommendation] It is recommended to call forward before any call to getWriter or getOutputStream, as we don’t know which one will be called in the forwarded resource.
You may include other servlets from the forwarded servlets and the rules remain same for including a servlet from any servlet. All included contents after a forward and until a commit or end of that forward will be part of response.