• SpringBoot 配置 Servlet、Filter、Listener


    https://www.cnblogs.com/pomer-huang/p/9639322.html

    https://blog.csdn.net/qq_38709999/article/details/99986797

    SpringBoot 配置 Servlet、Filter、Listener

    在SpringBoot应用中,嵌入式的 Servlet 3.0+ 容器不会直接使用 ServletContainerInitializer 和 WebApplicationInitializer,即通过以上两个接口实现的 Servlet、Filter、Listener 配置都是无效的,这是为了防止第三方代码的设计损坏应用程序,原文如下

    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.

    综上,可以采取以下配置

    配置策略一:ServletContextInitializer

    由官方原文可知,我们可以使用替代方案:ServletContextInitializer,示例如下

    @Configuration
    public class GoServletContextInitializer implements ServletContextInitializer {
    
        @Override
        public void onStartup(ServletContext servletContext) throws ServletException {
    
            //配置 Log4j Config Listener  
            servletContext.setInitParameter("log4jConfigLocation", "classpath:config/properties/log4j.properties");  
            servletContext.addListener(Log4jConfigListener.class);  
              
              
            //配置 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, "/*");
              
              
            //配置 statViewServlet  
            StatViewServlet statViewServlet = new StatViewServlet();
            ServletRegistration.Dynamic dynamic = servletContext.addServlet(
                    "statViewServlet", statViewServlet);
            dynamic.setLoadOnStartup(2);
            dynamic.addMapping("/druid/*");
        }
    }

    亲测,即使将 Spring Boot 打包成 war,并部署到 Tomcat 8.5,这份配置也是有效的


    配置策略二:ServletContextInitializer 的延伸

    请看类继承体系

    原理:最下边的三个子类会自动在运行时注册 Servlet、Listener、Filter(一定要将其定义为 Spring 容器的 Bean)

    1. ServletRegistrationBean:在Servlet容器初始化时,向 ServletContext 注册一个自定义的 Servlet
    2. ServletListenerRegistrationBean:在Servlet容器初始化时,向 ServletContext 注册一个自定义的 ServletContextListener
    3. AbstractFilterRegistrationBean:(模板方法模式)通过模板方法 getFilter(),将 Filter 的构建过程延迟到子类,并在Servlet容器初始化时,向 ServletContext 注册该 Filter。开发者可以定义一个子类来重写该模板方法,以配置一个自定义的 Filter。

    Servlet 配置示例

    @Configuration
    public class ServletConfig {
    
        //配置 StatViewServlet
        @Bean
        public ServletRegistrationBean servletRegistration0() {
            ServletRegistrationBean registration = new ServletRegistrationBean(new StatViewServlet());
            registration.addUrlMappings("/druid/*");
            registration.setLoadOnStartup(0);
            return registration;
        }
    }

    Filter 配置示例

    @Configuration
    public class FilterConfig {
    
        //配置 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
    public class ListenerConfig {
    
        //配置 RequestContextListener
        @Bean
        public ServletListenerRegistrationBean<RequestContextListener> listenerRegistration3() {
            return new ServletListenerRegistrationBean<>(
                new RequestContextListener());
        }
    }
     
    « 上一篇: SpringBoot 配置静态资源映射 
    » 下一篇: Spring Security Oauth2 示例
     
    ___________________________________________________________________________________________
    需求:springboot 启动后自动执行某些代码,初始化数据,并将数据放到 servletContext 中。
    
    首先,不可使用 ServletContextListener 即不能用 @WebListener ,因为 servlet 容器初始化后,spring 并未初始化完毕,不能使用 @Autowired 注入 spring 的对象。
    
    推荐使用 ApplicationListener:启动项目, spring 加载完毕后,才执行该 ApplicationListener,并且该 Listener 中可以使用 spring 的内容。
    
    @Component
    public class SettingDataInitListener implements ApplicationListener<ContextRefreshedEvent> {
        @Override
        public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
            // 将 ApplicationContext 转化为 WebApplicationContext 
            WebApplicationContext webApplicationContext = 
                (WebApplicationContext)contextRefreshedEvent.getApplicationContext();
            // 从 webApplicationContext 中获取  servletContext 
            ServletContext servletContext = webApplicationContext.getServletContext();
            // servletContext设置值
            servletContext.setAttribute("key", "value");
        }

    需求:springboot 启动后自动执行某些代码,初始化数据,并将数据放到 servletContext 中。

    首先,不可使用 ServletContextListener 即不能用 @WebListener ,因为 servlet 容器初始化后,spring 并未初始化完毕,不能使用 @Autowired 注入 spring 的对象。

    推荐使用 ApplicationListener:启动项目, spring 加载完毕后,才执行该 ApplicationListener,并且该 Listener 中可以使用 spring 的内容。

    1.  
      @Component
    2.  
      public class SettingDataInitListener implements ApplicationListener<ContextRefreshedEvent> {
    3.  
          @Override
    4.  
          public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
    5.  
              // 将 ApplicationContext 转化为 WebApplicationContext 
    6.  
              WebApplicationContext webApplicationContext = 
    7.  
                  (WebApplicationContext)contextRefreshedEvent.getApplicationContext();
    8.  
              // 从 webApplicationContext 中获取  servletContext 
    9.  
              ServletContext servletContext = webApplicationContext.getServletContext();
    10.  
              // servletContext设置值
    11.  
              servletContext.setAttribute("key", "value");
    12.  
          }
    13.  
  • 相关阅读:
    jQuery中$(function(){})与(function($){})(jQuery)、$(document).ready(function(){})等的区别详细讲解
    jQuery的三种$()方式
    基于DDD的.NET开发框架
    你得学会并且学得会的Socket编程基础知识
    C#委托及事件
    C#学习笔记:泛型委托Action<T>和Fun<TResult>
    JS 变量或参数是否有值的判断
    [转]剖析ASP.Net MVC Application
    python爬虫beautifulsoup4系列2【转载】
    python爬虫beautifulsoup4系列1【转载】
  • 原文地址:https://www.cnblogs.com/kelelipeng/p/11412138.html
Copyright © 2020-2023  润新知