Filter接口定义在javax.servlet
包中,是Servlet规范定义的,做用于Request/Response先后,被Servlet容器调用,Filter不能使用Spring容器资源。java
自定义的过滤器须要实现javax.servlet.Filter
,Filter接口中有三个方法:web
init(FilterConfig filterConfig)
:过滤器初始化的被调用。spring
doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
:在doFilter()
方法中,chain.doFilter()
前的通常是对request执行的过滤操做,chain.doFilter
后面的代码通常是对response执行的操做,chain.doFiter()
执行下一个过滤器或者业务处理器。bash
destory()
:过滤器销毁的时候被调用。ide
@Configuration
public class WebConfig{
@Bean
public FilterRegistrationBean xxxFilter() {
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
registrationBean.setFilter(new xxxFilter());
registrationBean.setUrlPatterns(Arrays.asList("/*"));
registrationBean.setOrder(1); // 过滤器的优先级
return registrationBean;
}
}
复制代码
@WebFilter
和@ServletComponentScan
经过@WebFilter
的方式定义Filter,默认使用Filter的类名设置优先级。使用FilterRegistrationBean
能够指定优先级。Filter使用白名单过滤Url的方式,配置须要拦截的Url,若是想设置不过滤某些Url须要在doFilter
方法中指定。post
定义一个Interceptor须要实现org.springframework.web.servlet.HandlerInterceptor
接口,Interceptor是Spring容器定义的,它可使用Spring容器的任何资源,只要经过IoC注入到Interceptor便可,Interceptor能够深刻到业务处理方法的执行先后和抛出异常的时候,而Filerter没法作到这一点,因此Interceptor相比Filter具备更大的弹性。ui
实现HandlerInterceptor
或者继承HandlerInterceptorAdapter
spa
public interface HandlerInterceptor {
default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return true;
}
default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
}
default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
}
}
复制代码
preHandle:在业务处理器处理请求以前被调用。3d
postHandle:在业务处理器处理请求后并生成视图前被调用,此时有机会修改ModelAndView。code
afterCompletion:业务处理处理器处理完请求后(已经渲染视图)被执行,并能够处理业务方法发生异常的场景。
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
InterceptorRegistration registration = registry.addInterceptor(new TimeInterceptor());
registration.excludePathPatterns("/user");
registration.excludePathPatterns("/*");
}
}
复制代码
Interceptor既能够指定要过滤的Url也能够指定不拦截的Url,缺省状况拦截全部Url。