Can we have multiple Servlet Filters?

As already briefed in Servlet , a Servlet is a Server Side Java Program, which runs on Web Server or Application Server, and provides HTTP response to the HTTP request received from a Web Browser, such as Filter does Preprocessing and post processing

A Servlet Filter is used to perform pre processing and post processing a request to a servlet.

How Servlet Filter can be used

Below are few scenarios where Filters can be used
1. To decrypt a request(received , and to encrypt response(before sending to client/browser)
2. For profiling purpose, how much time server takes to process a request, and respond.
3. To log client IP address, in a file or to a database table.
4. To block requests from certain range of IP address.

struts2 is dependent on servlet Filter concept, this shows how powerful Servlet Filter concept is.

Filter interface
Methods in Filter interface, which need to be implemented.

Deployment Descriptor web.xml

Multiple filters can be configured

Advantages of Servlet Filter

Filters are dynamically pluggable.
They can be plugged in, plugged out , without any source code changes.
Filter
Plugging and need not go through development cycle, and hence

How to configure Filter in web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">

    <filter>
    <filter-name>MyFilter

Filter example

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.*;

public class MyFilter implements Filter{

public void init(FilterConfig arg0) throws ServletException
{
    System.out.println("init() in MyFilter");
}

public void doFilter(ServletRequest req, ServletResponse resp,
    FilterChain chain) throws IOException, ServletException {

    PrintWriter out=resp.getWriter();

   //Do not process request from local host
    if(req.getRemoteAddr().equals("127.0.0.1"))
    {
        out.print("Your IP addr is blocked. Retry later");
        return;
    }

    out.print("<br>myfilter is invoked before");
    chain.doFilter(req, resp);//sends request to next resource

    out.print("<br>myfilter is invoked after");

    System.out.println("doFilter() in MyFilter");
    }

public void destroy() {
    System.out.println("destroy() in MyFilter");
    }
}

servlet code

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 NewServlet extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
         response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        out.print("<br>welcome to servlet<br>");
    }
}

struts2 is dependent on servlet Filter concept, this shows how powerful Servlet Filter concept is.

How to configure multiple Filters to a Servlet?

Yes, it is possible to have multiple Filters, which need to be configured in Deployment Descriptor(web.xml). The order in which these filters get invoked is the order in which they are configured in web.xml.

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">

        <filter>
        <filter-name>MyFilter</filter-name>
        <filter-class>MyFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>MyFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <filter>
        <filter-name>NewFilter</filter-name>
        <filter-class>NewFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>NewFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <servlet>
        <servlet-name>NewServlet</servlet-name>
        <servlet-class>NewServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>NewServlet</servlet-name>
        <url-pattern>/NewServlet</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
</web-app>

Below is an example of Web.xml, which has below two Filters

1. MyFilter.java - Logs Clients IP Address to Server Console, similarly,

Below is source code of NewFilter.java


Below is source code of MyFilter.java

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.*;

public class MyFilter implements Filter{

public void init(FilterConfig arg0) throws ServletException
{
    System.out.println("init() in MyFilter");
}

public void doFilter(ServletRequest req, ServletResponse resp,
    FilterChain chain) throws IOException, ServletException {

    PrintWriter out=resp.getWriter();


    if(req.getRemoteAddr().equals("127.0.0.1"))
    {
        out.print("Your IP addr is blocked. Retry later");
        return;
    }

    out.print("
myfilter is invoked before"); chain.doFilter(req, resp);//sends request to next resource out.print("
myfilter is invoked after"); System.out.println("doFilter() in MyFilter"); } public void destroy() { System.out.println("destroy() in MyFilter"); } }

2. NewFilter.java - Just prints log on Web Server Console

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.*;

public class NewFilter implements Filter{

public void init(FilterConfig arg0) throws ServletException
{
    System.out.println("init() in NewFilter");
}

public void doFilter(ServletRequest req, ServletResponse resp,
    FilterChain chain) throws IOException, ServletException {

    PrintWriter out=resp.getWriter();
    out.print("
filter is invoked before"); chain.doFilter(req, resp);//sends request to next resource out.print("
filter is invoked after"); System.out.println("doFilter() in NewFilter"); } public void destroy() { System.out.println("destroy() in NewFilter"); } }

No Source code changes are required in the servlet.

How to map Filter to a specific URLs or Servlet(s)?

It is possible to map Filters to a specific URLS or Servlet(s). This is possible by adjusting means it Filter gets invoked for all Servlets. By chaging it to below

Filter gets invoked only when urls starting with abc are requested, from Web Browser

    <filter-mapping>
        <filter-name>MyFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

You may also like to read:
What is Servlet Life Cycle?
What are implicit objects in JSP