In this tutorial, we are going to understand how to associate a chain of filters with a web resource. The web resource could be a Servlet, JSP or a static html webpage.
Using the feature of filter, we can perform many tasks within a web application such as - session validation, user authentication and verification
, restricting access to a particular web resource etc.
We can create multiple Filter classes by implementing the Filter interface. After associating
multiple Filter classes with a web resource, when a user make a request to a web resource,
the associated
Filter classes are executed before the before and after the web resource requested by the user
is executed, hence providing a filter to the user request and response.
Multiple filters associated with a web resource
are executed in the order of <filter-mapping> tag, which is specified in the deployment descriptor file(web.xml).
Methods of Filter interface
In order to create a filter class we must implement the three methods of javax.servlet.Filter interface.
This method is called by the web container when a client requests for a web resource
which could be a Servlet or a JSP page.
voiddestroy()
This method destroys the Filter instance.
Creating a webpage which calls the Servlet
We are creating a webpage which asks the user to enter his name and click the submit button,
which when clicked, will call a Servlet, but before this Servlet is executed, two filters associated with it
will be executed in the order of <filter-mapping> tag, which is specified in the deployment descriptor file(web.xml).
Webpage1.jsp
<html>
<head>
<title> Filters Demo </title>
</head>
<body>
<b> Please enter your name : ? </b>
<br/>
<br/>
<br/>
<form action ="MyServ">
Name : <input type = "text" name = "name" />
<input type = "submit" name = "submit" />
</form>
</body>
</html>
Creating Filter
Next, we are creating two Filters by implementing the Filter interface and by implementing its three methods -
And, within the doFilter(ServletRequest, ServletResponse, FilterChain) method, we must make a call to doFilter(request, response) method of FilterChain interface.
The call to doFilter(request, response) method calls any additional Filter attached to the Servlet.
If there is no more Filter attached to the Servlet, then the requested Servlet is finally executed.
After the servlet has finished its execution, the doFilter(request,response) method returns, enabling you to handle Servlet output in the response object.
MyFilter1.java
import java.io.*;
import javax.servlet.*;
public class MyFilter1 implements Filter
{
public void init(FilterConfig filterConfig)
{
}
public void destroy()
{
}
//This method is called each time a client requests for a web resource
// which could be a Servlet or a JSP page i.e. preprocessing request
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException
{
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<b> <i>Filter1 - Filtering request</i> </b>");
out.println("Hello " + request.getParameter("name") + "!");
out.println("<br/>");
out.println("<br/>");
out.println("<br/>");
//Calling doFilter() calls the next filter in the chain will execute or
//if there is no filter then the requested web resource is executed.
chain.doFilter(request,response);
out.println("<br/>");
out.println("<br/>");
out.println("<br/>");
//post-processing the request and after the requested web resource is called.
out.println("<b> <i>Filter2 - Filtering response</i> </b>");
out.println("Bye " + request.getParameter("name") + "!");
}
}
MyFilter2.java
import java.io.*;
import javax.servlet.*;
public class MyFilter1 implements Filter
{
public void init(FilterConfig filterConfig)
{
}
public void destroy()
{
}
//This method is called each time a client requests for a web resource
// which could be a Servlet or a JSP page i.e. preprocessing request
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException
{
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<b> <i>Filter2 - Filtering request</i> </b>");
out.println("Hello " + request.getParameter("name") + "!");
out.println("<br/>");
out.println("<br/>");
out.println("<br/>");
//Calling doFilter() calls the next filter in the chain will execute or
//if there is no filter then the requested web resource is executed.
chain.doFilter(request,response);
out.println("<br/>");
out.println("<br/>");
out.println("<br/>");
//post-processing the request and after the requested web resource is called.
out.println("<b> <i>Filter1 - Filtering response</i> </b>");
out.println("Bye " + request.getParameter("name") + "!");
}
}
MyServlet1.java is a Servlet class, which is executed after its associated filters are executed.
MyServlet1.java
import java.io.*;
import javax.servlet.*;
public class MyServlet1 extends GenericServlet
{
public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException
{
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("The requested Servlet is being executed.");
}
}
Advertisement
Directory Structure of Servlet files
The diagram above depicts how to arrange the Servlet files in a specific directory structure, as per Java Servlet Specification-
Project Folder - We have created a project folder named FilterChainEx within
the webapps folder of Tomcat installation folder. This folder contains the Servlet class(.java) file and WEB-INF folder.
WEB-INF - Within your project folder, you create another folder named WEB-INF and this folder should contain the deployment descriptor file(web.xml) of your Java Servlet program.
classes - Within the WEB-INF folder you should create a folder named classes. This folder should contain the compiled(.class) form of your Java Servlet class.
Creating the Deployment Descriptor file
As per the Java Servlet specifications, every web application based on Servlet must have a Deployment Descriptor file(an XML file) named web.xml.
So, let's create one and this time, associate our two filter classes with our Servlet class -
In deployment descriptor file, The <filter> has two child tags <filter-name> and <filter-class>.
<filter-name> tag is used to specify a unique name for our filter class, we have given it a unique name Filter1.
<filter-class> tag is used to specify the full qualified name of the filter class and in our example our filter class is named MyFilter1.
<servlet> has two child tags <servlet-name> and <servlet-class> :
<servlet-name> tag is used to specify a unique name for our Servlet class, we have given it a unique name Servlet.
<servlet-class> tag is used to specify the full qualified name of the Servlet class and in our example our Servlet class is named MyServlet1.
Note
The child tag <filter-name> of <filter> tag is matched with the <filter-name> child tag of
<filter-mapping>. The
<url-pattern> child tag of <filter-mapping>should be the same
as the <url-pattern> for our servlet i.e. MyServ.
The child tag <servlet-name> of <servlet> tag is matched with the <servlet-name> child tag of
<servlet-mapping>. The
<url-pattern> child tag is used to specify the URL to access Servlet and we have named this URL MyServ.
The order in which these Filters are executed depends on the order of <filter-mapping> tag described in the web.xml file. Hence, first the Filter1 is executed and then Filter2 is executed.
Setting the classpath
Much of the support for developing the web applications based on the Java Servlet technology does not come with the core Java.
Hence, in order to compile the Servlet programs, we have to set the classpath to a jar file named
servlet-api.jar.
This jar file provides all the classes that are required for the Servlet programming and it comes within the lib Folder of
Tomcat installation folder.
For example, in our case we have installed Tomcat Web Server within the C: Drive, hence the path to our lib folder containing the servlet-api.jar is - C:\apache-tomcat-9.0.2\lib
There are two ways to set the classpath -
You could set the classpath by entering this command at the Command Prompt, but this only temporarily sets the classpath to the path of servlet-api.jar file. If you restart your system, you will have to set the classpath again.
set classpath=C:\apache-tomcat-9.0.2\lib\servlet-api.jar
In order to set the classpath permanently, you need to set your classpath system variables. A simple tutorial on how to permanently set the classpath system variables, you may read
How to permanently set the classpath system variable
Compiling the Servlet class
After setting the classpath, you need to compile the filters and the Servlet class by entering the following commands at the folder, where you've stored the Servlet class file.
javac -d WEB-INF/classes MyFilter1.java
javac -d WEB-INF/classes MyFilter2.java
javac -d WEB-INF/classes MyServlet1.java
Executing the Servlet
We are creating a webpage which asks the user to enter his name and click the submit button.
First we execute the webpage containing the form, which asks the user to enter the name and press submit button.
On submitting the form, three activities takes place in the following order -
The requested servlet is called,
but before this Servlet is executed, the two filters associated with this Servlet will be executed, to filter the user request.
The order in which these Filters are executed depends on the order of <filter-mapping> tag described in the web.xml file. Hence, first the Filter1 is executed and then Filter2 is executed.
Next, the requested Servlet is executed.
And finally, the filters associated with the request Servlet are executed in the opposite order of how they were called to filter the response.
Hence, the user is presented with the following messages on the window.