Spring boot configuration Servlet, Filter, Listener
In spring boot applications, the embedded Servlet 3.0 + container will not directly use the ServletContainerInitializer and WebApplicationInitializer, that is, the Servlet, Filter and Listener configurations implemented through the above two interfaces are invalid, which is to prevent the design of the third-party code from damaging the application program. The original text is as follows
Embedded servlet containers will not directly execute the Servlet 3.0+ javax.servlet.ServletContainerInitializer interface, or Spring's org.springframework.web.WebApplicationInitializer interface. This is an intentional design decision intended to reduce the risk that 3rd party libraries designed to run inside a war will break Spring Boot applications.
If you need to perform servlet context initialization in a Spring Boot application, you should register a bean that implements the org.springframework.boot.context.embedded.ServletContextInitializer interface. The single onStartup method provides access to the ServletContext, and can easily be used as an adapter to an existing WebApplicationInitializer if necessary.
To sum up, the following configuration can be adopted
Configuration policy 1: ServletContextInitializer
From the official text, we can use the alternative: ServletContextInitializer, as shown in the following example
@Configuration public class GoServletContextInitializer implements ServletContextInitializer { @Override public void onStartup(ServletContext servletContext) throws ServletException { //Configure Log4j Config Listener servletContext.setInitParameter("log4jConfigLocation", "classpath:config/properties/log4j.properties"); servletContext.addListener(Log4jConfigListener.class); //Configure CharacterEncodingFilter FilterRegistration.Dynamic characterEncodingFilter = servletContext.addFilter("characterEncodingFilter", CharacterEncodingFilter.class); characterEncodingFilter.setInitParameter("encoding", "UTF-8"); characterEncodingFilter.setInitParameter("forceEncoding", "true"); characterEncodingFilter.addMappingForUrlPatterns( EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.INCLUDE), false, "/*"); //Configure statViewServlet StatViewServlet statViewServlet = new StatViewServlet(); ServletRegistration.Dynamic dynamic = servletContext.addServlet( "statViewServlet", statViewServlet); dynamic.setLoadOnStartup(2); dynamic.addMapping("/druid/*"); } }
Test by hand, even if Spring Boot is packaged as war and deployed to Tomcat 8.5, this configuration is effective
Configuration strategy 2: extension of ServletContextInitializer
See class inheritance system
Principle: the bottom three subclasses will automatically register Servlet, Listener and Filter at runtime (be sure to define it as the Bean of Spring container)
- ServletRegistrationBean: register a custom Servlet with the ServletContext when the Servlet container is initialized
- ServletListenerRegistrationBean: register a custom ServletContextListener with the ServletContext when the Servlet container is initialized
- AbstractFilterRegistrationBean: (template method mode) delay the construction process of the Filter to the subclass through the template method getFilter(), and register the Filter with the ServletContext when the Servlet container is initialized. Developers can define a subclass to override the template method to configure a custom Filter.
Sample Servlet configuration
@Configuration public class ServletConfig { //Configure StatViewServlet @Bean public ServletRegistrationBean servletRegistration0() { ServletRegistrationBean registration = new ServletRegistrationBean(new StatViewServlet()); registration.addUrlMappings("/druid/*"); registration.setLoadOnStartup(0); return registration; } }
Filter configuration example
@Configuration public class FilterConfig { //Configure CharacterEncodingFilter @Bean public FilterRegistrationBean filterRegistration1() { FilterRegistrationBean registration = new FilterRegistrationBean(new CharacterEncodingFilter()); registration.addUrlPatterns("/*"); Map<String, String> initParameters = Maps.newHashMap(); initParameters.put("encoding", "UTF-8"); initParameters.put("forceEncoding", "true"); registration.setInitParameters(initParameters); return registration; } }
Listener configuration example
@Configuration public class ListenerConfig { //Configure RequestContextListener @Bean public ServletListenerRegistrationBean<RequestContextListener> listenerRegistration3() { return new ServletListenerRegistrationBean<>( new RequestContextListener()); } }