5.10.4. Registration of Servlets and Filters

To use servlets and security filters, defined in the application component, in the owning application you need to register them in this component. The servlets are normally registered in the web.xml configuration file, however, this configuration is not propagated in the application where this app component is used.

The ServletRegistrationManager bean enables to register servlets and filters dynamically with correct ClassLoader and enables using such static classes as AppContext. It also guarantees the correct work for all deployment options.

ServletRegistrationManager has two methods:

  1. createServlet() - creates a servlet of the given servlet class. It loads the servlet class with the correct ClassLoader that is obtained from the application context object. It means that a new servlet will be able to use static classes, for example, AppContext or Messages bean.

  2. createFilter() - create filters in the same way.

In order to use this bean, we recommend creating a managed initializer bean in the application component. This bean should be annotated with the @Component annotation and contain event listeners that are subscribed to the application context initialization and destroy: ServletContextInitializedEvent and ServletContextDestroyedEvent.

An example of such bean:

@Component
public class WebInitializer {

    @Inject
    private ServletRegistrationManager servletRegistrationManager;

    @EventListener
    public void initializeHttpServlet(ServletContextInitializedEvent e) {
        Servlet myServlet = servletRegistrationManager.createServlet(e.getApplicationContext(), "com.demo.comp.MyHttpServlet");

        e.getSource().addServlet("my_servlet", myServlet)
                .addMapping("/myservlet/");
    }
}

Here, the WebInitializer class has only one event listener which is used to register an HTTP servlet from an application component in the owning application.

The createServlet() method takes the application context obtained from ServletContextInitializedEvent and the HTTP servlet FQN. Then we register the servlet by its name (my_servlet) and define HTTP-mapping (/myservlet/). Now, if you add this app component to you application, MyHttpServlet will be registered right after the initialization of servlet and application contexts.

For more complex example, see the Registering DispatcherServlet from Application Component section.

Registration of Servlets for single WAR deployment

For correct class loading of custom filters and servlets in single WAR deployment, follow the steps below:

  1. Create a class that extends javax.servlet.ServletContextListener. This class will be in charge of servlets/filters creation:

    public class CustomWebListener implements ServletContextListener {
        @Override
        public void contextInitialized(ServletContextEvent servletContextEvent) {
            ServletContext servletContext = servletContextEvent.getServletContext();
            registerServlet(servletContext);
        }
    
        @Override
        public void contextDestroyed(ServletContextEvent sce) {
        }
    
        protected void registerServlet(ServletContext servletContext) {
            Servlet testServlet = new TestServlet();
            ServletRegistration.Dynamic servletReg = servletContext.addServlet("test_servlet", cubaServlet);
            servletReg.setLoadOnStartup(0);
            servletReg.setAsyncSupported(true);
            servletReg.addMapping("/testServlet");
        }
    }
  2. Add a new parameter context-param in the single-war-web.xml file with the reference to the created class:

    <context-param>
        <param-name>webServletContextListener</param-name>
        <param-value>com.company.CustomWebListener</param-value>
    </context-param>