How do I create a servlet filter using Filter and FilterChain?

Creating a servlet filter using the Filter interface and FilterChain is straightforward in Jakarta EE (or Java EE). A filter is used to perform filtering tasks like logging, authentication, authorization, etc., on requests or responses. Here’s how you can create a servlet filter step by step:

Steps to Create a Servlet Filter

  1. Implement the Filter interface:
    • The Filter interface provides three methods to override: init(), doFilter(), and destroy().
  2. Configure the filter:
    • Filters can be configured either programmatically (via annotations) or declaratively (via web.xml).

1. Code Example of a Filter Implementation

package org.kodejava.servlet;

import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.FilterConfig;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.annotation.WebFilter;

import java.io.IOException;

// Use @WebFilter annotation to map the filter to a URL pattern
@WebFilter(urlPatterns = "/*") // This applies the filter to all URLs
public class MyServletFilter implements Filter {

   @Override
   public void init(FilterConfig filterConfig) throws ServletException {
      // Initialization logic (called once when the filter is first loaded)
      System.out.println("Initializing MyServletFilter...");
   }

   @Override
   public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
           throws IOException, ServletException {
      // Logic before passing request to the next filter or servlet
      System.out.println("Request intercepted by MyServletFilter!");

      // Pass the request/response to the next filter or the target servlet
      chain.doFilter(request, response);

      // Logic after the request is processed by the servlet/next filter
      System.out.println("Response processed by MyServletFilter!");
   }

   @Override
   public void destroy() {
      // Cleanup logic (called once when the filter is taken out of service)
      System.out.println("Destroying MyServletFilter...");
   }
}

2. Explanation of Methods in the Filter Interface

  1. init(FilterConfig filterConfig):
    • Called once when the filter is initialized.
    • Use this method for any one-time setup or resource allocation.
  2. doFilter(ServletRequest request, ServletResponse response, FilterChain chain):
    • The core method where the filtering logic is applied.
    • You can manipulate the request before calling chain.doFilter() to pass it along the filter chain or the servlet.
    • After chain.doFilter(), you can manipulate the response as needed.
  3. destroy():
    • This method is called once when the filter is being taken out of service (e.g., when the application is shutting down).
    • Use this for cleaning up resources (closing connections, releasing memory, etc.).

3. Configure the Filter in web.xml (Optional)

Instead of using the @WebFilter annotation, you can configure your filter in the web.xml file.

<filter>
    <filter-name>MyServletFilter</filter-name>
    <filter-class>com.example.MyServletFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>MyServletFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

4. How Filters Work in the Chain

  • Filters in the chain are invoked in the order they are mapped.
  • The doFilter() method ensures proper chaining of requests/responses by calling chain.doFilter() to pass the request to the next filter or servlet.
  • If you skip chain.doFilter(), the request won’t proceed further.

Example Workflow

  1. Before calling chain.doFilter():
    • You can add custom logic, such as logging the request or checking for specific headers, parameters, or cookies.
  2. After chain.doFilter():
    • You can modify the response, such as adding HTTP headers, statistics, etc.

Request flow for the above filter:

  1. A client sends a request.
  2. The filter intercepts the request.
  3. Pre-processing (before calling chain.doFilter()).
  4. Request is passed to the servlet or next filter (via chain.doFilter()).
  5. Post-processing (after chain.doFilter()).
  6. The client receives the response.

This is how servlet filters can be implemented to intercept and process requests and responses in Jakarta EE.


Maven dependencies

<dependency>
    <groupId>jakarta.servlet</groupId>
    <artifactId>jakarta.servlet-api</artifactId>
    <version>6.1.0</version>
    <scope>provided</scope>
</dependency>

Maven Central

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.