How to add a filter in Spring Boot | Java Development Journal

How to add a filter in Spring Boot

In this post, we will explore how to add a filter in Spring Boot and what are the options to configure these filters in Spring Boot.

 

Introduction

Filters as the name suggest use to perform filtering on either the request to a resource or on the response from a resource, or both. Spring Boot provides few options to register custom filters in the Spring Boot application. Let’s take a look at the different options.

 

1. Define Spring Boot Filter and Invocation Order

Simply implement Filter interface to create a new filter in Spring Boot.

@Configuration
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CustomFilter implements Filter {

 private static final Logger LOGGER = LoggerFactory.getLogger(CustomFilter.class);

 @Override
 public void init(FilterConfig filterConfig) throws ServletException {
  LOGGER.info("########## Initiating Custom filter ##########");
 }

 @Override
 public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

  HttpServletRequest request = (HttpServletRequest) servletRequest;
  HttpServletResponse response = (HttpServletResponse) servletRequest;

  LOGGER.info("Logging Request  {} : {}", request.getMethod(), request.getRequestURI());

  //call next filter in the filter chain
  filterChain.doFilter(request, response);

  LOGGER.info("Logging Response :{}", response.getContentType());
 }

 @Override
 public void destroy() {
  // TODO: 7/4/18
 }
}

Let’s quickly take a look at some of the important points in the above code

  • The filter registered by @Component annotation.
  • To fire filters in the right order – we needed to use the @Order annotation.

Highest order filter run first. This is really useful when we want to execute our custom filters on predefined order.

@Component
@Order(1)
public class CustomFirstFilter implements Filter {

}

@Component
@Order(2)
public class CustomSecondFilter implements Filter {

}

In the above code, CustomFirstFilter will run before the CustomSecondFilter.

The lower the number, the higher the precedence

 

2. URL Pattern

If the convention-based mapping is not flexible enough, we can use FilterRegistrationBean for the complete control of the application. In this case, don’t use @Component annotation for the filter class but register the filter using a FilterRegistrationBean.

public class CustomURLFilter implements Filter {

 private static final Logger LOGGER = LoggerFactory.getLogger(CustomURLFilter.class);

 @Override
 public void init(FilterConfig filterConfig) throws ServletException {
  LOGGER.info("########## Initiating CustomURLFilter filter ##########");
 }

 @Override
 public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

  HttpServletRequest request = (HttpServletRequest) servletRequest;
  HttpServletResponse response = (HttpServletResponse) servletResponse;

  LOGGER.info("This Filter is only called when request is mapped for /customer resource");

  //call next filter in the filter chain
  filterChain.doFilter(request, response);
 }

 @Override
 public void destroy() {

 }
}

Register the custom Filter using FilterRegistrationBean.

@Configuration
public class AppConfig {

 @Bean
 public FilterRegistrationBean < CustomURLFilter > filterRegistrationBean() {
  FilterRegistrationBean < CustomURLFilter > registrationBean = new FilterRegistrationBean();
  CustomURLFilter customURLFilter = new CustomURLFilter();

  registrationBean.setFilter(customURLFilter);
  registrationBean.addUrlPatterns("/greeting/*");
  registrationBean.setOrder(2); //set precedence
  return registrationBean;
 }
}

 

3. Controller

Let’s now create a simple controller and send an HTTP request to it:

@RestController
public class FilterExampleController {

 @GetMapping
 public String greeting() {
  return "Hello World";
 }

 @GetMapping(value = "/greeting")
 public String customGreetings() {
  return "Hello From Custom Greetings";
 }
}

When we start and run our application, following logs can be found in the console.

####################################################################  On Server startup ####################################################################
2018-07-04 17:22:32.221  INFO 40519 --- [ost-startStop-1] c.j.filters.CustomURLFilter              : ########## Initiating CustomURLFilter filter ##########
2018-07-04 17:22:32.222  INFO 40519 --- [ost-startStop-1] com.javadevjournal.filters.CustomFilter  : ########## Initiating Custom filter ##########


################################################################### On Hitting http://host:port/ ##############################################################
2018-07-04 17:22:56.710  INFO 40519 --- [nio-8080-exec-1] com.javadevjournal.filters.CustomFilter  : Logging Request  GET : /
2018-07-04 17:22:56.743  INFO 40519 --- [nio-8080-exec-1] com.javadevjournal.filters.CustomFilter  : Logging Response :text/html;charset=UTF-8


################################################################### On Hitting http://host:port/greeting #######################################################
2018-07-04 17:24:42.325  INFO 40519 --- [nio-8080-exec-5] com.javadevjournal.filters.CustomFilter  : Logging Request  GET : /greeting
2018-07-04 17:24:42.325  INFO 40519 --- [nio-8080-exec-5] c.j.filters.CustomURLFilter              : This Filter is only called when request is mapped for /customer resource
2018-07-04 17:24:42.327  INFO 40519 --- [nio-8080-exec-5] com.javadevjournal.filters.CustomFilter  : Logging Response :text/html;charset=UTF-8

 

Summary

In this post, we explore how to add a filter in Spring Boot. We covered the different options for creating and registering the custom filter in our Spring Boot application. Code snippets can be found GitHub

Leave a Reply

avatar

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

  Subscribe  
Notify of