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
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.
@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);
}
}
@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);
}
}
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.