내장 된 용기를 사용하여 봄 부팅, 어떻게 사용자 정의 필터를 구성하는 것이

Listener, Filter그리고 Servlet자바 웹 개발 과정은 일반적으로 세 가지 구성 요소를 사용하는 것을 특징으로 종종 간단한 처리 권한 요청 헤더을 방지하기 위해 필터링하는 데 사용되는 가장 높은 주파수 성분 필터, XSS공격을. 우리는 기존의 스프링 MVC 개발을 사용하는 경우에만 다음과 같은 구성 톰캣의 web.xml에 파일이 필요합니다 :

<!-- 配置Listener -->
<listener>
    <listener-class>org.springframework.web.util.WebAppRootListener</listener-class>
</listener>
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener> 

<!--配置Filter,这边配置了一个Filter,但是匹配了多个url-pattern-->
<!-- 以url-partern方式配置的filter中,如果有多个与当前请求匹配,则按web.xml中filter-mapping出现的顺序来运行-->
<filter>  
    <filter-name>filter1</filter-name>  
    <filter-class>com.csx.MyFilter</filter-class>  
</filter>  
<filter-mapping>
    <filter-name>filter1</filter-name>  
    <url-pattern>/url/a/*</url-pattern>  
</filter-mapping>  
<filter-mapping>  
    <filter-name>filter1</filter-name>  
    <url-pattern>/url/b/*</url-pattern>  
</filter-mapping>

<!--配置Servlet-->
<servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:springmvc.spring.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <!-- 这边不建议写成/* -->
    <url-pattern>/</url-pattern>
</servlet-mapping>

PS : 컨테이너가 시작되면, 세 구성 요소 위의 시동 시퀀스가 ​​수신기 인 -> 필터 -> 서블릿 측면 암웨이 메모리의 방법 (필터)를 발행 부트 시퀀스 "리 (청취자)에 메모리 분할 ( 서블릿) "가 될 수 있습니다.

web.xml의 구성이 세 가지 구성 요소는 비교적 간단하지만, 봄 부팅의 개발의 사용과 용기를 포함하는, 그리고 구성의 web.xml 파일에 우리를 허용하지 않았다. 그래서 결국 방법의 봄 부팅을 구성 Listener, Filter그리고 Servlet그것의 다른 구성 요소?

이 블로그 Filter열은의 봄 부팅을 구성하는 방법을 소개 Listener, FilterServlet기타 구성 요소.

한 가지 방법 : 필터 선언 콩

여기에 우리가 먼저 필터를 정의에서,이 효과는 통계적 인터페이스를 호출하는 시간 필터링합니다.

public class TimeConsumingCalculationFilter implements Filter {

        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            HttpServletRequest httpRequest=(HttpServletRequest)request;
            long startTime = System.nanoTime();
            logger.info(">>>>>>> Begin ["+httpRequest.getRequestURI()+"]...");
            try{
                chain.doFilter(request, response);
            }finally {
                long endTime = System.nanoTime();
                logger.info(">>>>>>> End ["+httpRequest.getRequestURI()+"]["+(endTime-startTime)/1000/1000.0+"ms].");
            }
        }

    }

봄 부팅 위의 필터 구성, 우리는 필요한 @Configuration파일에 다음과 같은 구성을 수행 :

@Configuration
public class WebConfig {

    private static Logger logger = LoggerFactory.getLogger(WebConfig.class);

    @Bean
    public Filter filter1(){
        return new TimeConsumingCalculationFilter();
    }
}

필터의 기본값은 위의 모든 요청을 차단합니다. 우리는 여러 인터셉터를 구성 할 경우, 그냥에 콩 방법을 추가 할 수 있습니다.

@Configuration
public class WebConfig {

    private static Logger logger = LoggerFactory.getLogger(WebConfig.class);

    @Bean
    public Filter filter1(){
        return new TimeConsumingCalculationFilter();
    }
    
    @Bean
    public Filter filter2() {
        return new TimeConsumingCalculationFilter2();
    }
}

이 구성 코드 구성 필터, 필터 기본적으로 위의 모든 요청이 순서 가로 두 개의 차단됩니다 필터 1 -> 필터 2. 제 1 논리의 측면은 차단 후 필터 구성 후 차단 필터로 구성. 우리가 명시 적으로 순서를 지정하려면 물론, 당신은의 도움을 차단할 수 있도록 @Order메모를. 그러나 참고이 댓글은 위에서 정의 된 클래스에 추가되어야합니다.

@Order(Ordered.LOWEST_PRECEDENCE - 2)
public class TimeConsumingCalculationFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
       //your logic
    }

}
@Order(Ordered.LOWEST_PRECEDENCE - 1)
public class TimeConsumingCalculationFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
       //your logic
    }

}

PS : 실행 우선 작을 @Order 값의 값이 클수록. 우선 순위가 높을수록 값이 작아. 우리는 실행 순서를 정의하는 시간 때문에, 사용하도록 권장 @Order(Ordered.LOWEST_PRECEDENCE - 1)좀 더 직관적으로 보이는 있도록 구성이 양식을, 더 큰는 Ordered.LOWEST_PRECEDENCE는, 가치, 더 높은 우선 순위를 뺀다.

또한, 스프링은 또한 제공 OrderedFilter인 인터페이스 FilterOrdered인터페이스들의 결합 및 원리는 상기와 동일하다. 당신은 상황을 볼 수 있습니다.

이 배열의 위의 장점은 구성에 매우 간단하지만, 단점도 분명, 구성의 기본을 차단하는 모든 요청에 ​​유연 충분하지 않습니다.

두 번째 방법 : @WebFilter 방법

@WebFilter주석이 서블릿에서 제공하는 내용이므로, 봄이 코멘트를 지원합니다. @WebFilter세분화 된 구성은 상기와 같이 더 유연 할 수있다.

@Configuration
public class WebConfig {
    //可以自定义url-pattern
    @WebFilter(urlPatterns="/*")
    @Order(Ordered.LOWEST_PRECEDENCE - 2)
    //这边如果不加`@Configuration`,需要通过`@ServletComponentScan`扫描`Listener`、`Filter`和`Servlet`这三个组件
    @Configuration
    public class TimeConsumingCalculationFilter implements Filter {

        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            //your logic
        }
    }   
    
    @WebFilter(urlPatterns="/*")
    @Order(Ordered.LOWEST_PRECEDENCE - 2)
    //这边如果不加`@Configuration`,需要通过`@ServletComponentScan`扫描`Listener`、`Filter`和`Servlet`这三个组件
    @Configuration
    public class TimeConsumingCalculationFilter2 implements Filter {

        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            //your logic
        }
    }   
    
}

함으로써 @WebFilter특수 필터 간단하고 사용자 및 URL 인터셉트 패턴 시퀀스 능력 배열.

세 가지 방법 : FilterRegistrationBean 구성을 사용하여

@Configuration
public class WebConfig {

    private static Logger logger = LoggerFactory.getLogger(WebConfig.class);

    @Bean
        public FilterRegistrationBean<Filter> filter1() {
            FilterRegistrationBean<Filter> registrationBean = new FilterRegistrationBean<>();
            registrationBean.setName("filter1");
            registrationBean.setOrder(Ordered.LOWEST_PRECEDENCE - 2);
            registrationBean.setFilter(new TimeConsumingCalculationFilter());
            registrationBean.addUrlPatterns("/foo/*");
            return registrationBean;
        }
    
    
        @Bean
        public FilterRegistrationBean<Filter> filter2() {
            FilterRegistrationBean<Filter> registrationBean = new FilterRegistrationBean<>();
            registrationBean.setName("filter2");
            registrationBean.setOrder(Ordered.LOWEST_PRECEDENCE - 3);
            registrationBean.setFilter(new TimeConsumingCalculationFilter1());
            registrationBean.addUrlPatterns("/*");
            registrationBean.addInitParameter("key1","value1");
            registrationBean.addInitParameter("key2","value2");
            //通过Servlet name匹配Filter,不建议使用
            registrationBean.addServletNames("name1");
            return registrationBean;
        }

}

주의 사항 :

  • 그것은 FilterRegistrationBean와 필터 사이에 하나 개의 관계입니다.
  • 자사에서는 setName (문자열 이름)를 호출하기 위해 여러 FilterRegistrationBean 필요가있는 경우, 그렇지 않으면 첫 번째 성공적으로 등록이 유효, 고유 한 이름을 선언합니다.
  • 필요한 경우 호출 시퀀스는 그 setOrder (INT 순서) 메소드를 호출하여 설정할 수 있도록한다.

네 가지 방법 DelegatingFilterProxyRegistrationBean 방법을 사용하여

@Configuration
public class WebConfig {
    
    @Bean("myFilter")
    //配置了DelegatingFilterProxyRegistrationBean后,这种方式配置的Filter不会生效了,只会拦截/foo/*的请求
    public Filter myFilter(){
        return new TimeConsumingCalculationFilter();
    }

    @Bean
    public DelegatingFilterProxyRegistrationBean delegatingFilterProxyRegistrationBean(){
        DelegatingFilterProxyRegistrationBean filterProxy = new DelegatingFilterProxyRegistrationBean("myFilter");
        filterProxy.addUrlPatterns("/foo/*");
        filterProxy.addInitParameter("targetFilterLifecycle","true");
        filterProxy.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico");
        filterProxy.setDispatcherTypes(DispatcherType.REQUEST);
        return filterProxy;
    }

}

FilterRegistrationBean 및 DelegatingFilterProxyRegistrationBean 차이 :

  • onStartup 방법을 통해 직접 필터를 등록 FilterRegistrationBean.
  • DelegatingFilterProxyRegistrationBean는 빈에 대응하는 필터를 통과하여 사용자의 조회의 ApplicationContext 인스턴스 이름 ApplicationContextAware 인터페이스를 달성하면서, Servlet3.0 + DelegatingFilterProxy 용기 등록 및 빈에 대응하는 프록시 객체를 생성한다.

유추 이해

  • 서블릿 @WebServlet 사용자 정의 추가하는 방법은 고용 ServletRegistrationBean 수 있습니다
  • 이벤트가 일반적인 모니터입니다, 메모를 리스너 방법도 @WebListener 또는 ServletListenerRegistrationBean를 사용할 수있는 사용자 정의 추가

기타 관련 카테고리

  • ServletComponentRegisteringPostProcessor
  • ServletComponentHandler
  • WebListenerHandler
  • WebFilterHandler
  • WebServletHandler

참고

  • https://blog.csdn.net/loveForever_xiang/article/details/101270633
  • https://www.liangzl.com/get-article-detail-121998.html
  • https://mp.weixin.qq.com/s/t8WdKEkYJuRApeEEOvXR_A
  • https://blog.csdn.net/andy_zhang2007/article/details/90399870
发布了184 篇原创文章 · 获赞 141 · 访问量 35万+

추천

출처blog.csdn.net/sinat_27535209/article/details/103960210