SpringBoot 配置 서블릿, 필터, 리스너

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

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

SpringBoot 配置 서블릿, 필터, 리스너

SpringBoot 애플리케이션에서 둘 이상의 인터페이스를 통해 서블릿 3.0 컨테이너와 직접적 ServletContainerInitializer WebApplicationInitializer을, 즉 매립 구현 서블릿, 필터, 수신기 구성은 외부 코드의 애플리케이션에 대한 손상을 방지하도록 설계되어, 잘못 다음과 같이 프로그램은 읽기

임베디드 서블릿 컨테이너는 직접 서블릿 3.0 javax.servlet.ServletContainerInitializer 인터페이스를 실행하거나 봄의 org.springframework.web.WebApplicationInitializer 인터페이스하지 않습니다. 이 제 3의 라이브러리는 봄 부팅 응용 프로그램을 중단하는 전쟁 내에서 실행하도록 설계 위험을 줄이기위한 의도적 인 디자인 결정이다.

당신이 봄 부팅 응용 프로그램에서 서블릿 컨텍스트 초기화를 수행해야하는 경우 org.springframework.boot.context.embedded.ServletContextInitializer 인터페이스를 구현하는 bean을 등록해야합니다. 단일 onStartup 방법은 ServletContext에 대한 액세스를 제공하고, 필요한 경우 쉽게 기존 WebApplicationInitializer에 어댑터로서 사용될 수있다.

요약하면, 다음과 같은 구성을 취할 수

구성 정책 : 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/*"); } }

봄 부팅 WAR로 포장하고, 톰캣 8.5에 배포 프로 테스트, 경우에도,이 구성은 효과적이다


구성 전략 2 : ServletContextInitializer의 확장

클래스 상속 시스템을 참조하십시오

원리 : 맨 아래 세 개의 서브 클래스가 자동으로 실행 서블릿, 리스너, 필터에 등록한다 (확인은 콩 스프링 컨테이너로 정의 할 수 있습니다)

  1. ServletRegistrationBean : 서블릿 컨테이너를 초기화 할 때, ServletContext를 사용자 정의 서블릿을 등록
  2. ServletListenerRegistrationBean : 서블릿 컨테이너를 초기화 할 때, ServletContext를 사용자 정의 ServletContextListener를 등록
  3. AbstractFilterRegistrationBean :( 템플릿 방법)을 getFilter 템플릿 (방법), 공정 지연 필터의 서브 클래스를 구축하고, 서블릿 컨테이너를 초기화 할 때, ServletContext 내 필터를 등록 할 수 있습니다. 개발자는, 템플릿 메소드를 오버라이드 (override) 사용자 정의를 구성하는 필터하기 위해 서브 클래스를 정의 할 수 있습니다.

서블릿 구성 예

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

구성 예제 필터

@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; } }

리스너 구성 예

@Configuration
public class ListenerConfig { //配置 RequestContextListener @Bean public ServletListenerRegistrationBean<RequestContextListener> listenerRegistration3() { return new ServletListenerRegistrationBean<>( new RequestContextListener()); } }
 
<<  이전 :  SpringBoot는 정적 자원 매핑을 구성  
>>  다음 기사 :  봄 보안 OAuth2를 예를
 
___________________________________________________________________________________________
수요 : 일부 springboot 시작 코드, 초기화 데이터의 servletContext에 데이터를 자동화 할 수 있습니다. 

먼저, 즉, 사용되지 않을 수 ServletContextListener @WebListener가 초기화 서블릿 컨테이너 때문에, 스프링은 초기화되지 않은 개체 스프링 @Autowired 주입을 사용할 수 없다. 

권장 만약 ApplicationListener는 : 단지 만약 ApplicationListener를 구현 한 후로드 된 프로젝트, 봄을 시작하고 리스너 봄의 컨텐츠를 사용할 수 있습니다. 

@Component 
공용  클래스 SettingDataInitListener 유단 만약 ApplicationListener <ContextRefreshedEvent> { 
    @Override 
    공개  공극 onApplicationEvent (ContextRefreshedEvent ContextRefreshedEvent) {
         // WebApplicationContext에서 내로의 ApplicationContext 
        WebApplicationContext에서의 WebApplicationContext = 
            (의 WebApplicationContext) contextRefreshedEvent.getApplicationContext (); 
        // 从의 WebApplicationContext中获取의 servletContext 
        의 ServletContext의 servletContext = webApplicationContext.getServletContext ();
        // 의 servletContext设置值 
        servletContext.setAttribute ( "키", "값" ); 
    }

 

수요 : 일부 springboot 시작 코드, 초기화 데이터의 servletContext에 데이터를 자동화 할 수 있습니다.

먼저, 즉, 사용되지 않을 수 ServletContextListener @WebListener가 초기화 서블릿 컨테이너 때문에, 스프링은 초기화되지 않은 개체 스프링 @Autowired 주입을 사용할 수 없다.

권장 만약 ApplicationListener는 : 단지 만약 ApplicationListener를 구현 한 후로드 된 프로젝트, 봄을 시작하고 리스너 봄의 컨텐츠를 사용할 수 있습니다.

  1.  
    @구성 요소
  2.  
    공공 클래스 SettingDataInitListener가 구현 만약 ApplicationListener를 < ContextRefreshedEvent > {
  3.  
        @보수
  4.  
        공공 무효 onApplicationEvent (ContextRefreshedEvent contextRefreshedEvent) {
  5.  
            의 WebApplicationContext에 // ApplicationContext를 
  6.  
            의 WebApplicationContext의 WebApplicationContext = 
  7.  
                (의 WebApplicationContext) contextRefreshedEvent.getApplicationContext ();
  8.  
            의 WebApplicationContext에서 ServletContext를 얻기 // 
  9.  
            ServletContext에의 servletContext webApplicationContext.getServletContext = ();
  10.  
            //하는 ServletContext 설정
  11.  
            servletContext.setAttribute ( "키" , "값" );
  12.  
        }
  13.  

在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 템플릿 (방법), 공정 지연 필터의 서브 클래스를 구축하고, 서블릿 컨테이너를 초기화 할 때, ServletContext 내 필터를 등록 할 수 있습니다. 개발자는, 템플릿 메소드를 오버라이드 (override) 사용자 정의를 구성하는 필터하기 위해 서브 클래스를 정의 할 수 있습니다.

서블릿 구성 예

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

구성 예제 필터

@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; } }

리스너 구성 예

@Configuration
public class ListenerConfig { //配置 RequestContextListener @Bean public ServletListenerRegistrationBean<RequestContextListener> listenerRegistration3() { return new ServletListenerRegistrationBean<>( new RequestContextListener()); } }

추천

출처www.cnblogs.com/kelelipeng/p/11412138.html