Showing posts with label FilterChain. Show all posts
Showing posts with label FilterChain. Show all posts

Thursday, 1 May 2014

Servlets : Multiple Filter Demo

Master Java Web Architecture!

Subscribe to Ram N Java for clean, hands-on tutorials on Java Servlets, FilterChains, and real-world backend design patterns!

🔔 Subscribe to Ram N Java

What is Filter Chaining in Java Servlets?

In Java web applications, a Servlet Filter intercepts incoming requests before they reach a servlet and inspects outgoing responses before they return to the client browser. When multiple filters are configured for the same URL pattern, the servlet container arranges them in a sequential pipeline called a FilterChain.

Each filter performs a specific task—such as logging request details, validating user credentials, or compressing response streams—and then invokes chain.doFilter(request, response) to hand off control to the next filter in line or to the target servlet.

Combining Authentication and Logging Filters

In this practical demonstration, two distinct filters work together seamlessly to protect and monitor a web resource:

  • LoggingFilter: Intercepts every incoming request first, capturing useful client metadata such as IP address, requested URI, and incoming timestamp before passing control down the chain.
  • AuthenticationFilter: Inspects user credentials or session tokens. If the credentials are valid, it passes control to the destination servlet; if invalid, it halts the chain immediately and redirects or displays an error message.
// Inside doFilter method of LoggingFilter:
System.out.println("Incoming Request from IP: " + request.getRemoteAddr());
chain.doFilter(request, response); // Passes request to AuthenticationFilter
System.out.println("Response sent back to client.");

// Inside doFilter method of AuthenticationFilter:
if (isValidUser(request)) {
    chain.doFilter(request, response); // Passes request to target Servlet
} else {
    response.getWriter().println("Authentication Failed: Access Denied!");
}

How Execution Order is Determined

  • web.xml Configuration: The container executes filters in the exact order in which their <filter-mapping> elements are declared in web.xml.
  • Pre-Processing & Post-Processing: Code placed before chain.doFilter() runs before the servlet executes; code placed after chain.doFilter() executes during the response phase.
  • Separation of Concerns: Keeping cross-cutting concerns (security, audit logging) in separate filters keeps your servlets clean and maintainable.

Recommended Related Tutorials

Learn more about filters and servlet security with these handpicked tutorials from Ram N Java:


Click here to watch in Youtube : https://www.youtube.com/watch?v=BXL3FE3b6ic

Click the below Image to Enlarge

MultilpleFiltersDemo Project Dir Structure

LogFilter.java
import java.io.IOException;
import java.util.Date;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

public class LogFilter implements Filter
{

    public void init(FilterConfig config) throws ServletException
    {
        System.out
                .println("------------------------------------------------------");
        System.out.println(" init method is called in "
                + this.getClass().getName());
        System.out
                .println("------------------------------------------------------");
    }

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

        System.out.println(" doFilter method is called in "
                + this.getClass().getName() + "\n\n");

        HttpServletRequest request = (HttpServletRequest) req;

        // Get the IP address of client machine.
        String ipAddress = request.getRemoteAddr();

        // Log the IP address and current timestamp.
        System.out.println("IP " + ipAddress + ", Time "
                + new Date().toString() + "\n\n");

        chain.doFilter(req, res);

    }

    public void destroy()
    {
        // add code to release any resource
        System.out
                .println("------------------------------------------------------");
        System.out.println(" destroy method is called in "
                + this.getClass().getName());
        System.out
                .println("------------------------------------------------------");
    }
}

AuthenticationFilter.java
import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class AuthenticationFilter implements Filter
{

    public void init(FilterConfig config) throws ServletException
    {
        System.out
                .println("------------------------------------------------------");
        System.out.println(" init method is called in "
                + this.getClass().getName());
        System.out
                .println("------------------------------------------------------");
    }

    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException
    {
        System.out.println(" doFilter method is called in "
                + this.getClass().getName() + "\n\n");

        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;

        String userName = req.getParameter("username");
        String passWord = req.getParameter("password");

        if (!(userName.equalsIgnoreCase("ram") && passWord.equals("ram")))
        {
            System.out
                    .println("######################################################");
            System.out.println("Unauthorized request");
            System.out
                    .println("######################################################\n\n");
            res.sendRedirect("index.html");
        }
        else
        {
            // pass the request along the filter chain
            chain.doFilter(request, response);
        }

    }

    public void destroy()
    {
        // add code to release any resource
        System.out
                .println("------------------------------------------------------");
        System.out.println(" destroy method is called in "
                + this.getClass().getName());
        System.out
                .println("------------------------------------------------------");
    }
}

HelloWorldServlet.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 HelloWorldServlet extends HttpServlet
{

    private static final long serialVersionUID = 1L;

    public void init() throws ServletException
    {
        System.out
                .println("------------------------------------------------------");
        System.out.println(" Init method is called in "
                + this.getClass().getName());
        System.out
                .println("------------------------------------------------------");
    }

    // Method to handle GET method request.
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException
    {

        System.out.println(" doGet method is called in "
                + this.getClass().getName() + "\n\n");
        System.out
                .println("------------------------------------------------------");

        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        out.print("Hello World <br>");

    }

    public void destroy()
    {
        System.out
                .println("------------------------------------------------------");
        System.out.println(" destroy method is called in "
                + this.getClass().getName());
        System.out
                .println("------------------------------------------------------");
    }
}

web.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    metadata-complete="true" version="3.0">
    <display-name>MultilpleFiltersDemo</display-name>
    <description>
        This is a simple web application with a source code organization
        based on the recommendations of the Application Developer's Guide.
    </description>
    <servlet>
        <servlet-name>hello</servlet-name>
        <servlet-class>HelloWorldServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>

    <filter>
        <filter-name>LogFilter</filter-name>
        <filter-class>LogFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>LogFilter</filter-name>
        <url-pattern>/hello</url-pattern>
    </filter-mapping>

    <filter>
        <filter-name>AuthFilter</filter-name>
        <filter-class>AuthenticationFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>AuthFilter</filter-name>
        <url-pattern>/hello</url-pattern>
    </filter-mapping>

</web-app>

index.html
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Multiple Filters Demo</title>
</head>
<body>
    <form action="hello" method="GET">
        
        UserName :  <input type="text" name="username" /><br /> 
        
        Password :&nbsp; &nbsp; <input type="password" name="password" /><br /> 
            
        <input type="submit" value="login" />
        
    </form>
</body>
</html>


Environment Used

JDK version :1.6.0_30
Tomcat version : 7.0.50

To Download MultilpleFiltersDemoApp Project Click the below link

https://sites.google.com/site/javaee4321/servlets/MultilpleFiltersDemoApp.zip?attredirects=0&d=1

See also:

  • Servlets Tutorial
  • All Design Patterns Links
  • Wednesday, 23 April 2014

    Servlets : FilterChain

    Master Core Java & Servlets!

    Subscribe to Ram N Java for clear, beginner-friendly explanations, web architecture deep dives, and hands-on coding demos!

    🔔 Subscribe to Ram N Java

    What is FilterChain in Java Servlets?

    In Java web applications, the FilterChain interface (provided by javax.servlet) represents the invocation sequence of multiple filters applied to a particular web resource, such as a servlet or JSP page.

    When a browser makes an HTTP request that matches several configured filters, the servlet container does not execute them in isolation. Instead, it constructs a FilterChain object and passes it to each filter's doFilter() method. This mechanism allows multiple filters to intercept, inspect, and modify the request and response in an organized, stepwise sequence.

    How the doFilter Method Works

    The FilterChain interface defines a single, crucial method:

    public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException;

    When a filter calls chain.doFilter(request, response), one of two things happens:

    • If another filter exists in the chain: The web container invokes the next filter in line.
    • If it is the last filter in the chain: The web container invokes the destination servlet or web resource itself.

    If a filter decides not to invoke chain.doFilter(), the execution halts immediately. This is commonly used in authentication or validation filters to block unauthorized access from reaching the target servlet.

    Execution Order and Lifecycle Flow

    • Order of Execution: The servlet container determines filter invocation order based strictly on the sequence of <filter-mapping> entries in web.xml.
    • Symmetrical Two-Way Processing: Code placed before chain.doFilter() runs on the way in (request phase), while code placed after chain.doFilter() runs on the way back (response phase).
    • Clean Decoupling: Individual tasks like logging, authorization, and character encoding remain cleanly separated into focused, reusable components.

    Recommended Related Tutorials

    Continue exploring servlet filters and web architecture with these tutorials from Ram N Java:


    Click here to watch in Youtube : https://www.youtube.com/watch?v=ADI9IMivvKA

    Click the below Image to Enlarge
    Servlets : FilterChain
    See also:

  • Servlets Tutorial
  • All Design Patterns Links
  • Tutorials