- Servlet filters are a new addition to the servlet 2.3 realized in Oct 2000
- Definition:
- Filters have a wide array of uses; the Servlet 2.3 specification suggests the following uses:
- authentication filters
- logging and auditing filters
- image conversion filters
- data compression filters
- encryption filters
- tokenizing filters
- filters that trigger resource access events
- XSL/T filters that transform XML content
- MIME-type chain filters
Writing a Simple Filter
The first step in
learning how to write a filter is to look at a very simple example. A filter is
simply a Java class that implements the javax.servlet.Filter interface. The javax.servlet.Filter interface defines three methods
- public void doFilter
(ServletRequest request, ServletResponse response, FilterChain chain)
- public FilterConfig
getFilterConfig()
- public void setFilterConfig
(FilterConfig filterConfig)
- It is the containers responsibility to create a javax.servlet.FilterConfig object and pass it to the filter during initialization. The javax.servlet.FilterConfig object can be used to
- retrieve the filter name (as defined in the deployment descriptor),
- retrieve the initial parameters (as defined in the deployment descriptor), and
- get a reference to the ServletContext object the user is calling from
The setFilterConfig() method can be used to
capture the object into an attribute of the filter. The doFilter() method is where the
filter's work is done, in which you can parse the user's request; log
statistics to a file; manipulate the response back to the client; and so on.
Listing 1 is an example of a very simple filter which prints a message to the
console of the web server while it is filtering the request, calls the Servlet,
and then prints another message to the console while it is filtering the
response.
above diagram of how the simple filter fits into the
servlet's request-response model
Sample Program for Filters
servletex.java
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class servletex extends HttpServlet {
public servletex() {
System.out.println("Servlet Object has been created");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("servlet method is executing");
PrintWriter pw=response.getWriter();
pw.println("<br>servlet method is executing<br>"); }
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("servlet method is executing");
}
}
filter1.java
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class SimpleFilter implements Filter {
public SimpleFilter() {
}
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
try
{
System.out.print ("Within Simple Filter ... ");
System.out.println ("Filtering the Request ...");
PrintWriter pw=response.getWriter();
pw.println("before filter");
chain.doFilter (request, response);
pw.println("<br>after fileter");
System.out.print ("Within Simple Filter ... ");
System.out.println ("Filtering the Response ...");
} catch (IOException io) {
System.out.println ("IOException raised in SimpleFilter");
} catch (ServletException se) {
System.out.println ("ServletException raised in SimpleFilter");
}
}
public void init(FilterConfig fConfig) throws ServletException {
}
}
Web.xml
<web-app>
<servlet>
<description></description>
<display-name>simpleservelt</display-name>
<servlet-name>simpleservelt</servlet-name>
<servlet-class>simpleservelt</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>simpleservelt</servlet-name>
<url-pattern>/simple</url-pattern>
</servlet-mapping>
<filter>
<display-name>SimpleFilter</display-name>
<filter-name>SimpleFilter</filter-name>
<filter-class>SimpleFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SimpleFilter</filter-name>
<url-pattern>/simple</url-pattern>
</filter-mapping>
</web-app>
Filters with JSP
Logging.jsp
<%@ page
language="java" %>
<html>
<head>
<title>Logging Filter
Example</title>
</head>
<body>
<h1>Logging Filter</h1>
This filter writes log file of Tomcat
Web Server.
<hr>
See log file of Web server.
<br>
</body>
<%
System.out.println("jsp program is
executing");
%>
</html>
LoggingFilterExample.java
import
java.io.*;
import
javax.servlet.*;
import
javax.servlet.http.*;
public final class LoggingFilterExample implements Filter
{
private FilterConfig
filterConfigObj = null;
public void init(FilterConfig
filterConfigObj) {
this.filterConfigObj =
filterConfigObj;
System.out.println("init
method of filter is executed");
}
public void
doFilter(ServletRequest request,
ServletResponse response,
FilterChain chain)
throws IOException,
ServletException
{
System.out.println("servlet program is
being executed");
String remoteAddress = request.getRemoteAddr();
String uri =
((HttpServletRequest) request).getRequestURI();
String protocol =
request.getProtocol();
chain.doFilter(request,
response);
System.out.println("servelt program is executed");
}
public void destroy() {
System.out.println("destory method is
executed");
}
}
Web.xml
<web-app>
<display-name>Welcome
to Tomcat</display-name>
<description>Welcome to Tomcat</description>
<filter>
<filter-name>LoggingFilterExample</filter-name>
<filter-class>LoggingFilterExample</filter-class>
</filter>
<filter-mapping>
<filter-name>LoggingFilterExample</filter-name>
<url-pattern>/logging.jsp</url-pattern>
</filter-mapping>
</web-app>
Filter
Chaining
In the
first example only one filter that handled the request and response for the
simple servlet. What if you want multiple filters to handle the request and
response?
Filter1.java
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;
import javax.servlet.ServletException;
public class Filter1 implements Filter
{
private FilterConfig filterConfig;
public void doFilter (ServletRequest request,
ServletResponse response,
FilterChain chain)
{
try
{
System.out.print ("Within First Filter ... ");
System.out.println ("Filtering the Request ...");
chain.doFilter (request, response);
System.out.print ("Within First Filter ... ");
System.out.println ("Filtering the Response ...");
} catch (IOException io) {
System.out.println ("IOException raised in Filter1 Filter");
} catch (ServletException se) {
System.out.println ("ServletException raised in Filter1 Filter");
}
}
public FilterConfig getFilterConfig()
{
return this.filterConfig;
}
public void setFilterConfig (FilterConfig filterConfig)
{
this.filterConfig = filterConfig;
}
}
Filter2.java
import
javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;
import javax.servlet.ServletException;
public class Filter2 implements Filter
{
private FilterConfig filterConfig;
public void doFilter (ServletRequest request,
ServletResponse response,
FilterChain chain)
{
try
{
System.out.print ("Within Second Filter ... ");
System.out.println ("Filtering the Request ...");
chain.doFilter (request, response);
System.out.print ("Within Second Filter ... ");
System.out.println ("Filtering the Response ...");
} catch (IOException io) {
System.out.println ("IOException raised in Filter2 Filter");
} catch (ServletException se) {
System.out.println ("ServletException raised in Filter2 Filter");
}
}
public FilterConfig getFilterConfig()
{
return this.filterConfig;
}
public void setFilterConfig (FilterConfig filterConfig)
{
this.filterConfig = filterConfig;
}
}
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;
import javax.servlet.ServletException;
public class Filter2 implements Filter
{
private FilterConfig filterConfig;
public void doFilter (ServletRequest request,
ServletResponse response,
FilterChain chain)
{
try
{
System.out.print ("Within Second Filter ... ");
System.out.println ("Filtering the Request ...");
chain.doFilter (request, response);
System.out.print ("Within Second Filter ... ");
System.out.println ("Filtering the Response ...");
} catch (IOException io) {
System.out.println ("IOException raised in Filter2 Filter");
} catch (ServletException se) {
System.out.println ("ServletException raised in Filter2 Filter");
}
}
public FilterConfig getFilterConfig()
{
return this.filterConfig;
}
public void setFilterConfig (FilterConfig filterConfig)
{
this.filterConfig = filterConfig;
}
}
SimpleServlet.java
Public
class SimpleServlet implements HttpServlet
{
//logic
}
Web.xml
<filter>
<filter-name>
First Filter in Chain
</filter-name>
<filter-class>
com.filters.Filter1
</filter-class>
</filter>
<filter>
<filter-name>
Second Filter in Chain
</filter-name>
<filter-class>
com.filters.Filter2
</filter-class>
</filter>
<filter-mapping>
<filter-name>
First Filter in Chain
</filter-name>
<url-pattern>
/simple
</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>
Second Filter in Chain
</filter-name>
<url-pattern>
/simple
</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>
Simple Servlet
</servlet-name>
<servlet-class>
com.servlets.SimpleServlet
</servlet-class>
Parsing
a User's Request and Using Initial Parameters
So far
the examples of the filters have been trivial. Now it's time to do something
more realistic. Sometimes you may want to use a filter to verify certain
objects pass with the requests, such as elements from an HTML form. You may
want to verify the existence and validity of the values. If they don't exist,
you send the client's request to one servlet. If they do exist but the values
are not valid, then they are sent to a different servlet. Finally, if the
elements check out, they are passed to the requested servlet. Figure 6 shows a
diagram of this scenario.
Let's
take this example one step further. Not only do we want to verify HTML form
data, we want to retrieve the names of the HTML form elements from
initialization parameters. This means that if the HTML form changes, we do not
need to change any code in the filter; we simply change the initialization parameters
for the filter.
Initialization
parameters can be specified in the deployment descriptor. They are specified
when the filter is defined. Listing 6 is the code for the filter that retrieves
HTML form element names from initialization parameters, verifies the form data,
and sends the request to the appropriate servlet.
Filter1.java
import
javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.RequestDispatcher;
import java.util.Enumeration;
import java.io.IOException;
import javax.servlet.ServletException;
public class filter1 implements Filter
{
private FilterConfig filterConfig;
public void doFilter (ServletRequest request,
ServletResponse response,
FilterChain chain)
{
RequestDispatcher rd = null;
boolean emptyform = false;
try
{
Enumeration initParams = filterConfig.getInitParameterNames();
// no initial parameters so invoke next element in chain
if (initParams == null)
{
System.out.println("No elements to verify");
chain.doFilter(request, response);
}
// grab init param values and get the form elements
else
{
while (initParams.hasMoreElements())
{
String name = (String) initParams.nextElement();
String value = filterConfig.getInitParameter(name);
String formElement = request.getParameter(value);
// check to see if element exists (i.e. form was sent)
if (formElement == null)
{
rd = request.getRequestDispatcher("/noform");
rd.forward(request, response);
}
// check to see if elements are empty
else if (formElement.equals(""))
{
emptyform = true;
}
}
// a form element was empty
if (emptyform)
{
rd = request.getRequestDispatcher("/emptyform");
rd.forward(request, response);
}
// form was filled out properly
else
{
chain.doFilter(request, response);
}
}
}
catch (IOException io)
{
System.out.println("IOException raised");
}
catch (ServletException se)
{
System.out.println("ServletException raised");
}
}
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.RequestDispatcher;
import java.util.Enumeration;
import java.io.IOException;
import javax.servlet.ServletException;
public class filter1 implements Filter
{
private FilterConfig filterConfig;
public void doFilter (ServletRequest request,
ServletResponse response,
FilterChain chain)
{
RequestDispatcher rd = null;
boolean emptyform = false;
try
{
Enumeration initParams = filterConfig.getInitParameterNames();
// no initial parameters so invoke next element in chain
if (initParams == null)
{
System.out.println("No elements to verify");
chain.doFilter(request, response);
}
// grab init param values and get the form elements
else
{
while (initParams.hasMoreElements())
{
String name = (String) initParams.nextElement();
String value = filterConfig.getInitParameter(name);
String formElement = request.getParameter(value);
// check to see if element exists (i.e. form was sent)
if (formElement == null)
{
rd = request.getRequestDispatcher("/noform");
rd.forward(request, response);
}
// check to see if elements are empty
else if (formElement.equals(""))
{
emptyform = true;
}
}
// a form element was empty
if (emptyform)
{
rd = request.getRequestDispatcher("/emptyform");
rd.forward(request, response);
}
// form was filled out properly
else
{
chain.doFilter(request, response);
}
}
}
catch (IOException io)
{
System.out.println("IOException raised");
}
catch (ServletException se)
{
System.out.println("ServletException raised");
}
}
public
FilterConfig getFilterConfig()
{
return this.filterConfig;
}
public void setFilterConfig (FilterConfig filterConfig)
{
this.filterConfig = filterConfig;
}
}
{
return this.filterConfig;
}
public void setFilterConfig (FilterConfig filterConfig)
{
this.filterConfig = filterConfig;
}
}
web.xml
<web-app> <filter>
<filter-name>
Parsing Request Data
</filter-name>
<filter-class>
com.filters.RequestFilter
</filter-class>
<init-param>
<param-name>
User's Name
</param-name>
<param-value>
myname
</param-value>
</init-param>
<init-param>
<param-name>
User's Email
</param-name>
<param-value>
txtemail
</param-value>
</init-param>
</filter>
<!-- Map the filter to a Servlet or URL -->
<filter-mapping>
<filter-name>
Parsing Request Data
</filter-name>
<url-pattern>
/formprocessor
</url-pattern>
</filter-mapping>
<!-- Define the Servlets within the Web Application -->
<servlet>
<servlet-name>
No Form Submitted
</servlet-name>
<servlet-class>
com.servlets.NoElements
</servlet-class>
</servlet>
<servlet>
<servlet-name>
Empty Form Elements
</servlet-name>
<servlet-class>
com.servlets.InvalidEntries
</servlet-class>
</servlet>
<servlet>
<servlet-name>
Good Request
</servlet-name>
<servlet-class>
com.servlets.MyServlet
</servlet-class>
</servlet>
<!-- Define Servlet mappings to urls -->
<servlet-mapping>
<servlet-name>
No Form Submitted
</servlet-name>
<url-pattern>
/noform
</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>
Empty Form Elements
</servlet-name>
<url-pattern>
/emptyform
</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>
Good Request
</servlet-name>
<url-pattern>
/formprocessor
</url-pattern>
</servlet-mapping>
</web-app>
<filter-name>
Parsing Request Data
</filter-name>
<filter-class>
com.filters.RequestFilter
</filter-class>
<init-param>
<param-name>
User's Name
</param-name>
<param-value>
myname
</param-value>
</init-param>
<init-param>
<param-name>
User's Email
</param-name>
<param-value>
txtemail
</param-value>
</init-param>
</filter>
<!-- Map the filter to a Servlet or URL -->
<filter-mapping>
<filter-name>
Parsing Request Data
</filter-name>
<url-pattern>
/formprocessor
</url-pattern>
</filter-mapping>
<!-- Define the Servlets within the Web Application -->
<servlet>
<servlet-name>
No Form Submitted
</servlet-name>
<servlet-class>
com.servlets.NoElements
</servlet-class>
</servlet>
<servlet>
<servlet-name>
Empty Form Elements
</servlet-name>
<servlet-class>
com.servlets.InvalidEntries
</servlet-class>
</servlet>
<servlet>
<servlet-name>
Good Request
</servlet-name>
<servlet-class>
com.servlets.MyServlet
</servlet-class>
</servlet>
<!-- Define Servlet mappings to urls -->
<servlet-mapping>
<servlet-name>
No Form Submitted
</servlet-name>
<url-pattern>
/noform
</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>
Empty Form Elements
</servlet-name>
<url-pattern>
/emptyform
</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>
Good Request
</servlet-name>
<url-pattern>
/formprocessor
</url-pattern>
</servlet-mapping>
</web-app>
No comments:
Post a Comment