1. IMPLEMENTING AND CONFIGURING SERVLETS, FILTERS AND LISTENERS IN SPRING BOOT APPLICATIONS

Let’s say you find yourself modernizing a legacy Java web application, not just the UI libraries but also the middleware. And let’s say that Spring Boot was the selected framework to get the job done because of its many advantages:

  • Allows teams getting started quickly reducing boilerplate code.
  • Provides starter projects which extremely reduces Maven configuration, especially dependencies management.
  • Production ready actuator endpoints reporting metrics, health check.
  • Provides opiniated autoconfiguration out of the box flexible enough to be overriden when needed.
  • Seamless integration with the Spring ecosystem.

How can a Filter, a Servlet and a Listener be added to a Spring Boot application now that it lacks the web.xml file descriptor? This post answers this question also covering injecting dependencies to a Filter, Servlet or Listener.

2. REQUIREMENTS

  • Java 7 or 8.
  • Maven 3.2+.
  • Familiarity with Spring Framework.

3. APPLICATION DEPENDENCIES

pom.xml:

...
<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>1.5.10.RELEASE</version>
  <relativePath/> <!-- lookup parent from repository -->
</parent>
...
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>
...
<build>
  <plugins>
    <plugin>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-maven-plugin</artifactId>
    </plugin>
    ...
  </plugins>
  ...
</build>
...

In this example Spring Boot dependencies are included via a parent pom, you can also read on if you are interested in adding Spring Boot support using the bom approach.

spring-boot-starter-web transitively includes dependencies required to implement a Filter, Servlet or Listener.

spring-boot-maven-plugin allows Spring Boot applications to be packages as a jar or war archive and it from command line using Maven or Gradle. Visit the spring-boot-maven-plugin page to learn more.

4. SERVLETS

4.1. IMPLEMENTING A SERVLET
package com.asimio.web.servlet;
...
public class AsimioTechServlet extends HttpServlet {
...
  @Override
  protected void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    ...
  }

  @Override
  protected void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    ...
  }
}

A very simple Servlet.

4.2. REGISTERING A SERVLET

Let’s register it using Spring Boot’s ServletRegistrationBean:

package com.asimio.main;
...
@Configuration
public class AppConfig {
  ...
  @Bean
  public ServletRegistrationBean asimioTechServletRegistrationBean() {
    ServletRegistrationBean result = new ServletRegistrationBean(
      new AsimioTechServlet(), "/<url-map>");  // Comma separated url paths.
    result.setName("asimioTechServlet");
    result.setOrder(1);
    ...
    return result;
  }
...
}

Spring Boot beans are instantiated in @Configuration-annotated classes. If more than one servlet is going to be registered then the name for each ServletRegistrationBean bean would have to be explicitly set in @Bean annotations.

5. FILTERS

5.1. IMPLEMENTING A FILTER
package com.asimio.web.filter;
...
public class AsimioTechFilter implements Filter {

  @Override
  public void doFilter(ServletRequest request, ServletResponse ressponse,
      FilterChain chain) throws IOException, ServletException {
    ...
  }

  @Override
  public void init(FilterConfig filterConfig) throws ServletException {
	...	
  }

  @Override
  public void destroy() {
    ...
  }
}

An ordinary Servlet Filter.

5.2. REGISTERING A FILTER

Let’s now register a couple of Filters using Spring Boot’s FilterRegistrationBean:

...
@Bean
public FilterRegistrationBean sitemeshRegistrationBean() {
  FilterRegistrationBean result = new FilterRegistrationBean(new SiteMeshFilter());
  result.setName("sitemeshFilter");
  result.addUrlPatterns("*.html");  // Comma separated url patterns.
  result.setOrder(1);
  return result;
}

@Bean
public FilterRegistrationBean filter1RegistrationBean() {
  FilterRegistrationBean result = new FilterRegistrationBean(new AsimioTechFilter());
  result.setName("asimioTechFilter");
  result.addServletRegistrationBeans(
    Arrays.asList(this.asimioTechServletRegistrationBean()));  // List of ServletRegistrationBean
  result.setOrder(2);
  ...
  return result;
}
...
}

Again, if more than one filter is going to be registered then the name for each FilterRegistrationBean bean would have to be explicitly set in @Bean annotations. Also notice that similar to how they could be configured in web.xml, Filters could be mapped to url patterns as well as to servlets in Spring Boot web applications.

6. LISTENERS

6.1. IMPLEMENTING A LISTENER

package com.asimio.web.listener;
...
public class AsimioTechServletContextListener implements ServletContextListener {

  @Override
  public void contextInitialized(ServletContextEvent e) {
    ...
  }

  @Override
  public void contextDestroyed(ServletContextEvent e) {
    ...
  }
}

Another simple Servlet Listener implementation.

6.2. REGISTERING A LISTENER

A Java web application Servlet Listener could be registered using Spring Boot’s ServletListenerRegistrationBean:

...
@Bean
public ServletListenerRegistrationBean<ServletContextListener> asimioTechServletContextListenerRegistrationBean() {
  ServletListenerRegistrationBean<ServletContextListener> result =  new ServletListenerRegistrationBean<>();
  result.setListener(new AsimioTechServletContextListener());
  result.setName("asimioTechServletContextListenerRegistrationBean");
  result.setOrder(1);
  ...
  return result;
}
...

As a reminder, if more than one listener is going to be registered then the name for each ServletListenerRegistrationBean bean would have to be set in each listener @Bean annotation.

Also worth mentioning if you need to use a common set of Filters, Servlets and / or Listeners in multiple Spring Boot applications, you could pack them in their own custom Spring Boot starter and include it in Spring Boot applications with minimal configuration.

Hope you this post helpful, thanks for reading and feedback is always appreciated. If you found this post helpful and would like to receive updates when content like this gets published, sign up to the newsletter.