Generic Top

I just announced the new Learn Spring course, focused on the fundamentals of Spring 5 and Spring Boot 2:

>> CHECK OUT THE COURSE

1. Overview

The DispatcherServlet is the front controller in Spring web applications. It's used to create web applications and REST services in Spring MVC. In a traditional Spring web application, this servlet is defined in the web.xml file.

In this tutorial, we'll migrate code from a web.xml file to DispatcherServlet in a Spring Boot application. Also, we'll map Filter, Servlet, and Listener classes from web.xml to the Spring Boot application.

2. Maven Dependency

First, we have to add the spring-boot-starter-web Maven dependency to our pom.xml file:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

3. DispatcherServlet

DispatcherServlet receives all of the HTTP requests and delegates them to controller classes.

Before the Servlet 3.x specification, DispatcherServlet would be registered in the web.xml file for a Spring MVC application. Since the Servlet 3.x specification, we can register servlets programmatically using ServletContainerInitializer.

Let's see a DispatcherServlet example configuration in the web.xml file:

<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>
        org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

Spring Boot provides the spring-boot-starter-web library for developing web applications using Spring MVC. One of the main features of Spring Boot is autoconfiguration. The Spring Boot autoconfiguration registers and configures the DispatcherServlet automatically. Therefore, we don’t need to register the DispatcherServlet manually.

By default, the spring-boot-starter-web starter configures DispatcherServlet to the URL pattern “/”. So, we don't need to complete any additional configuration for the above DispatcherServlet example in the web.xml file. However, we can customize the URL pattern using server.servlet.* in the application.properties file:

server.servlet.context-path=/demo
spring.mvc.servlet.path=/baeldung

With these customizations, DispatcherServlet is configured to handle the URL pattern /baeldung and the root contextPath will be /demo. Thus, DispatcherServlet listens at http://localhost:8080/demo/baeldung/.

4. Application Configuration

Spring MVC web applications use the web.xml file as a deployment descriptor file. Also, it defines mappings between URL paths and the servlets in the web.xml file.

This is no longer the case with Spring Boot. If we need a special filter, we can register it in a Java class configuration. The web.xml file includes filters, servlets, and listeners.

When we want to migrate from a traditional Spring MVC to a modern Spring Boot application, how can we port our web.xml to a new Spring Boot application? In Spring Boot applications, we can add these concepts in several ways.

4.1. Registering a Filter

Let's create a filter by implementing the Filter interface:

@Component
public class CustomFilter implements Filter {

    Logger logger = LoggerFactory.getLogger(CustomFilter.class);

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

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
      throws IOException, ServletException {
        logger.info("CustomFilter is invoked");
        chain.doFilter(request, response);
    }

    // other methods 
}

Without Spring Boot, we would configure our CustomFilter in the web.xml file:

<filter>
    <filter-name>customFilter</filter-name>
    <filter-class>CustomFilter</filter-class>
</filter>

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

In order for Spring Boot to be able to recognize a filter, we just needed to define it as a bean with the @Component annotation.

4.2. Registering a Servlet

Let's define a servlet by extending the HttpServlet class:

public class CustomServlet extends HttpServlet {

    Logger logger = LoggerFactory.getLogger(CustomServlet.class);

    @Override
    protected void doGet(
        HttpServletRequest req,
        HttpServletResponse resp) throws ServletException, IOException {
            logger.info("CustomServlet doGet() method is invoked");
            super.doGet(req, resp);
    }

    @Override
    protected void doPost(
        HttpServletRequest req,
        HttpServletResponse resp) throws ServletException, IOException {
            logger.info("CustomServlet doPost() method is invoked");
            super.doPost(req, resp);
    }
}

Without Spring Boot, we would configure our CustomServlet in the web.xml file:

<servlet>
    <servlet-name>customServlet</servlet-name>
    <servlet-class>CustomServlet</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>customServlet</servlet-name>
    <url-pattern>/servlet</url-pattern>
</servlet-mapping>

In a Spring Boot application, the servlet is registered either as a Spring @Bean or by scanning the @WebServlet annotated classes with an embedded container.

With the Spring @Bean approach, we can use the ServletRegistrationBean class to register the servlet.

So, we'll define CustomServlet as a bean with the ServletRegistrationBean class:

@Bean
public ServletRegistrationBean customServletBean() {
    ServletRegistrationBean bean = new ServletRegistrationBean(new CustomServlet(), "/servlet");
    return bean;
}

4.3. Registering a Listener

Let's define a listener by extending the ServletContextListener class:

public class CustomListener implements ServletContextListener {

    Logger logger = LoggerFactory.getLogger(CustomListener.class);

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        logger.info("CustomListener is initialized");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        logger.info("CustomListener is destroyed");
    }
}

Without Spring Boot, we would configure our CustomListener in the web.xml file:

<listener>
    <listener-class>CustomListener</listener-class>
</listener>

To define a listener in a Spring Boot application, we can use either the @Bean or @WebListener annotations.

With the Spring @Bean approach, we can use the ServletListenerRegistrationBean class to register the Listener.

So, let's define CustomListener as a bean with the ServletListenerRegistrationBean class:

@Bean
public ServletListenerRegistrationBean<ServletContextListener> customListenerBean() {
    ServletListenerRegistrationBean<ServletContextListener> bean = new ServletListenerRegistrationBean();
    bean.setListener(new CustomListener());
    return bean;
}

Upon starting our application, we can check the log output to see confirmation that the listener has been successfully initialized:

2020-09-28 08:50:30.872 INFO 19612 --- [main] c.baeldung.demo.listener.CustomListener: CustomListener is initialized

5. Conclusion

In this quick tutorial, we saw how to define DispatcherServlet and web.xml elements including filter, servlet, and listener in a Spring Boot application. And, as always, the source code for the above example can be found over on GitHub.

Generic bottom

I just announced the new Learn Spring course, focused on the fundamentals of Spring 5 and Spring Boot 2:

>> CHECK OUT THE COURSE
guest
0 Comments
Inline Feedbacks
View all comments