How to use RequestDispatcher in Servlet - BunksAllowed

BunksAllowed is an effort to facilitate Self Learning process through the provision of quality tutorials.

Community

How to use RequestDispatcher in Servlet

Share This


While developing a web application, it is quite common that a Servlet (if not said otherwise, Servlet means HTTPServlet) has to dispatch its incoming request to any other resources on the server like an HTML page or JSP or any other Servlet, etc.

To do this, Servlet API has provided an Interface RequestDispatcher in javax.servlet package.


In this tutorial, we shall examine this Interface and shall discuss how it could be used to dispatch requests to other resources.

The RequestDispatcher interface defines an object which is held by a servlet (the source) and is used to wrap around a target resource (in most cases, it is another servlet) on the server so that the source can dispatch its request to the target. 

Here you might get confused with the idea that how can an object be created out of an Interface. As per Java norms, the reference of an interface can hold the object of the implementing class. javax.servlet provides different ways (which will be discussed shortly after) to create an object of the implementing class of RequestDispatcher and thus by accessing that object (from a source servlet) you can use all the functionalities described in RequestDispatcher.

Please take a note of it that the following is the chronology of actions that you have to perform in order to work with RequestDispatcher
  • Create a source servlet and a target servlet that has to dispatch its request
  • Obtain an object of RequestDispatcher within the source servlet and at the same time bind the target servlet (or any other resource) to that.
  • With the help of that object of RequestDispatcher, dispatch the request of the source to the target

So in the beginning, let us create a source servlet and a target servlet. The source servlet has to dispatch the request to the target servlet.
Coding SourceServ.java
@WebServlet("/SourceServ") public class SourceServ extends HttpServlet { private static final long serialVersionUID = 1L; public SourceServ() { super(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }



Coding TargetServ.java
@WebServlet("/TargetServ") public class TargetServ extends HttpServlet { private static final long serialVersionUID = 1L; public TargetServ() { super(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }



Next comes the question of obtaining the RequestDispatcher object inside either doGet or doPost methods. The following discussion clarifies how you can obtain the object of RequestDispatcher



How to obtain RequestDispatcher object

There are three ways that we can take to obtain the object of RequestDispatcher.

You can get the RequestDispatcher object by calling the RequestDispatcher getRequestDispatcher(String path) method on the object of HttpRequest object bound to the source servlet. Here the String parameter path holds the relative path of the target resource within the same servlet context as that of the source.

If the target is not in the same servlet context as that of the source, then essentially you are sending null as the parameter. So please do keep in mind that your source servlet and target resource must reside within the same servlet context

Here in our discussion, the target servlet is TargetServ.java and the source is SourceServlet.java and let us also consider that both of them are placed in the same package that is within the same servlet context. Hence, We could get the RequestDispatcher object in the doGet() method (let's say) like following
@WebServlet("/SourceServ") public class SourceServ extends HttpServlet { private static final long serialVersionUID = 1L; public SourceServ() { super(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { RequestDispatcher rd = request.getRequestDispatcher("TargetServ"); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
The second way is to call the RequestDispatcher getRequestDispatcher(String path) on the object of ServletContext of the source servlet. The parameter path holds the relative path of the target resource in the same servlet context as that of the source servlet.
You can do it by following
@WebServlet("/SourceServ") public class SourceServ extends HttpServlet { private static final long serialVersionUID = 1L; public SourceServ() { super(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ServletContext ctx = getServletContext(); RequestDispatcher rd = ctx.getRequestDispatcher("TargetServ"); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }

The third way is to call RequestDispatcher getNamedDispatcher(String name) method on the object of servlet context corresponding to the source servlet. Here the parameter name is the name of the target resource instead of the physical resource path as we were passing in getRequestDispatcher method of HttpRequest or ServletContext objects earlier. Here in our discussion, the name of the target servlet is nothing but urlPattern set to the TargetServlet.
We can do it by following

@WebServlet("/SourceServ") public class SourceServ extends HttpServlet { private static final long serialVersionUID = 1L; public SourceServ() { super(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ServletContext ctx = getServletContext(); RequestDispatcher rd = ctx.getNamedDispatcher("TargetServ"); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }



Though you can use any of the three ways discussed to get the object of RequestDispatcher , still, the first way is the most common, and hence in the subsequent discussions will use the first method to get the RequestDispatcher object.

So till now, we have created the source and target servlets and obtained the RequestDispatcher object in the source servlet; and the RequestDispatcher object wraps the target servlet. Now with the help of the RequestDispatcher object we should dispatch the request of the source servlet to the target servlet.



To do this, there are two methods defined in RequestDispatcher interface. and they are
  • void forward(ServletRequest request, ServletResponse response)
  • void include(ServletRequest request, ServletResponse response)
Next, we will discuss, how to use these two methods


forward method of RequestDispatcher

The signature of the forward method of RequestDispatcher is like void forward (ServletRequest request, ServletResponse response) .

It forwards the client request (and the response too) of the source servlet to the target servlet so that the target servlet can work on the request of the source servlet as per its own business logic and ultimately generate the response. This response generated by the target servlet is sent back to the client. 

Please note that if you are using the forward method, then the client has no scope of getting back the response generated by the source servlet, it has to accept the response generated by the target servlet. 

Hence, once the source servlet forwards the request to the target servlet, it has no further potential functionalities which could be sent back to the client. So in general calling forward method, logically, should be the last line of the corresponding logic within the source servlet.



include method of RequestDispatcher

The signature of the include method of RequestDispatcher is like void include(ServletRequest request,ServletResponse response) .

It includes the response of the target servlet to the existing response of the source servlet after the source servlet has dispatched its request to the target servlet and the target servlet has processed the dispatched request according to its business logic.

This essentially means that first, the source servlet will dispatch its own request through calling include method (maybe after processing it as per its own logic and maybe after generating its partial response) to the target servlet. Then target servlet will process the dispatched request and generate its own response. Lastly, the response generated by the target will be included (concatenated) to the existing response of the source servlet, and (maybe the source can further generate its own response at this time) the entire response will be sent back to the client.

Hence logically, as the source can create its own response, then can include the target's response, and then once again can generate its own response, there is no meaningful restriction that the include call in the source servlet should be the at last.

Now we will have a sample application that will illustrate how could we use forward and include method of RequestDispatcher


Sample application To illustrate forward and include methods

Here we present a sample application that demonstrates the usages of the forward and the include methods.

This sample application computes the tax of a taxpayer of a country XYZ where the Male and Female have different tax rates and the defense personnel of that XYZ country enjoy a special rebate
The codes of this application are self-explanatory with detailed comments. If you have gone through the above discussions, you will be able to walk through the codes without any doubt.
Following are the files in the application.
  • index.html - generates the view for application input by the clients
  • SourceServ.java - source servlet which fixes the tax rate based on gender and decides if a special rebate has to be applied or not. this servlet calls forward and include methods of RequestDispatcher object based on conditions.
  • TargetOneServ.java - target servlet which receives the forwarded request from the source and computes tax without any rebate
  • TargetTwoServ.java - target servlet which receives the included request from the source and computes tax with a rebate

The codes are given below

Coding index.html

<!DOCTYPE html> <html> <head> <meta charset="ISO-8859-1"> <title>BunksAllowed- RequestDispatcher Example</title> </head> <body> <h2>RequestDispatcher Example Through a Sample Income Tax Calculation Application</h2> <hr> <h3> Fill Up Tax Computation Form</h3> <form action="SourceServ" method="post"> <label> Last Year Income</label> <br> <input type="text" name="income"> <br> <label> Gender (M/F)</label> <br> <input type="text" name="gender"> <br> <label> Are you a defence personnel? (Yes / No)</label> <br> <input type="text" name="isdp"> <br> <input type="submit" value="Calculate Tax"> </form> <div align="center"> <p>© <a href="http://www.bunksallowed.com">BunksAllowed</a> 2018</p> </div> </body> </html>

Coding SourceServ.java
import java.io.IOException; import java.io.PrintWriter; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Servlet implementation class SourceServ */ @WebServlet("/SourceServ") public class SourceServ extends HttpServlet { private static final long serialVersionUID = 1L; private static final int TAX_RATE_MALE = 15; // tax rate for male in percentage private static final int TAX_RATE_FEMALE = 10; // tax rate for female in percentage public SourceServ() { super(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String gender = request.getParameter("gender"); String isDefencePersonnel = request.getParameter("isdp"); Integer rateValue; // setting income tax rate as per gender if (gender.equals("F")) rateValue = new Integer(TAX_RATE_FEMALE); else rateValue = new Integer(TAX_RATE_MALE); // setting the computed income tax rate to the existing request as attribute request.setAttribute("rate", rateValue); if (isDefencePersonnel.equals("No")) { // if the person is not from defense, forward the request for final tax // computation by TargetOneServ servlet // the dispatched request holds income and income tax rate information RequestDispatcher rd = request.getRequestDispatcher("TargetOneServ"); rd.forward(request, response); // Client will receive the response of TargetOneSer, SourceServ can not sent the // response back // This is the last code of the logic } else { // If the person is from defense // Generating own response response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println( "As you in defense, you are entitled to have en excemption of 5% in Income Tax rate."); // including the request for final tax computation with rebate by TargetTwoServ // servlet RequestDispatcher rd = request.getRequestDispatcher("TargetTwoServ"); rd.include(request, response); // Here we have response of SourceServ + response of TargetTwoServ // Generating the response of SourceServ once again out.println( "
As you are a defense personnel you could enjoy extra 2 working days to submit your tax"); // Now we have response of SourceServ + response of TargetTwoServ + response of // SourceServ } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }


Coding TargetOneServ.java
import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Servlet implementation class TargetServ */ @WebServlet("/TargetOneServ") public class TargetOneServ extends HttpServlet { private static final long serialVersionUID = 1L; public TargetOneServ() { super(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Getting the income amount from the dispatched request of SourceServ String incomeStr = request.getParameter("income"); double income = Integer.parseInt(incomeStr); // Getting the tax rate drom the dispatched request as computed and set by the // SourceServ int taxRate = (Integer) request.getAttribute("rate"); // Computing the tax amount double taxValue = income * (taxRate / 100.00); // Generating and sending the response back to client response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println( "
Here is your Tax amount:: " + taxValue + "
Pay the Income Tax within seven working days"); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }


Coding TargetTwoServ.java
import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Servlet implementation class TargetTwoServ */ @WebServlet("/TargetTwoServ") public class TargetTwoServ extends HttpServlet { private static final long serialVersionUID = 1L; private static final double REBATE = 5.00; // Rebate in tax rate for defense people in percentage /** * @see HttpServlet#HttpServlet() */ public TargetTwoServ() { super(); // TODO Auto-generated constructor stub } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse * response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Getting the income amount from the dispatched request of SourceServ String incomeStr = request.getParameter("income"); double income = Integer.parseInt(incomeStr); // Getting the tax rate drom the dispatched request as computed and set by the // SourceServ int taxRate = (Integer) request.getAttribute("rate"); // Computing the tax amount for defense people with rebate double taxValue = income * ((taxRate - REBATE) / 100.00); // Generating the response response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println( "
Here is your Tax amount:: " + taxValue + "
Pay the Income Tax within seven working days"); // This response will be concatenated with response of SourceServ } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse * response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }


I hope, you have thoroughly enjoyed this tutorial!

Happy Exploring!



No comments:

Post a Comment

Note: Only a member of this blog may post a comment.