请求拦截(HandlerInterceptor & Filter & @WebFilter)

David 2022-09-28 23:33:45
Categories: Tags:

 

 

  1. 拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用

 

  1. Filterservlet前后起作用。而拦截器执行在方法前后,异常抛出前后,因此拦截器具有更大的弹性

 

Filter->

Interceptor.preHandle->

Handler->

Interceptor.postHandle->

Interceptor.afterCompletion->

Filter->

 

因此所有在spring框架中应该优先使用拦截器。

 

  1. 拦截器则可以通过IoC容器来管理,因此可以通过注入等方式来获取其他Bean的实例,因此使用会更方便。

 

  1. 拦截器的执行过程是在过滤器的doFilter中执行的,可以多次调用,过滤器的初始化会在项目启动时执行,只能初始化一次

 

 

 

 

Filter 过滤器

 

 

注解方式

 

 

属性名

描述

filterName

指定过滤器的 name 属性,等价于 <filter-name>

value

该属性等价于 urlPatterns 属性。但是两者不应该同时使用。

urlPatterns

指定一组过滤器的 URL 匹配模式。等价于 <url-pattern> 标签。

servletNames

指定过滤器将应用于哪些 Servlet。取值是 @WebServlet 中的 name 属性的取值,或者是 web.xml <servlet-name> 的取值。

dispatcherTypes

指定过滤器的转发模式。具体取值包括: ASYNCERRORFORWARDINCLUDEREQUEST

initParams

指定一组过滤器初始化参数,等价于 <init-param> 标签。

asyncSupported

声明过滤器是否支持异步操作模式,等价于 <async-supported> 标签。

description

该过滤器的描述信息,等价于 <description> 标签。

displayName

该过滤器的显示名,通常配合工具使用,等价于 <display-name> 标签。

 

示例

@WebFilter(urlPatterns = "/*",filterName = "filter2")

public class FilterAnnotationTest implements Filter {

 

    @Override

    public void init(FilterConfig filterConfig) throws ServletException {

        System.out.println("过滤器2开始初始化");

    }

 

    @Override

    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        System.out.println("过滤器2开始工作");

        filterChain.doFilter(servletRequest,servletResponse);

    }

 

    @Override

    public void destroy() {

        System.out.println("过滤器2销毁");

    }

}

 

代码方式

直接重写实现Filter接口,在添加 @Configuration 注解的配置类中使用 FilterRegistrationBean 注册

示例

public class FilterDemo implements Filter {

 

    @Override

    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;

        System.out.println("过滤器开始工作。。"+httpServletRequest.getRequestURL());

        filterChain.doFilter(servletRequest,servletResponse);

    }

 

    @Override

    public void destroy() {

        System.out.println("过滤器开始销毁");

    }

}

 

然后利用filterRegistrationBean来进行注册

示例

@Configuration

public class FilterDemo {

    @Bean

    @Order(2)

    //spring boot会按照order值的大小,从小到大的顺序来依次过滤

    public FilterRegistrationBean configFilter(){

        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();

        filterRegistrationBean.setFilter(new FilterDemo());

        filterRegistrationBean.addUrlPatterns("/*");

        filterRegistrationBean.setName("sessionFilter");

        //filterRegistrationBean.setOrder(2);

        return filterRegistrationBean;

    }

}

 

 

 

HandlerInterceptor 拦截器

 

  1. 编写拦截器实现类AdminInterceptor,实现接口HandlerInterceptor

示例

public class AdminInterceptor implements  HandlerInterceptor {

 

     // 在请求处理之前进行调用(Controller方法调用之前)

    @Override

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {

        // System.out.println("执行了TestInterceptorpreHandle方法");

        try {

            //统一拦截(查询当前session是否存在user(这里user会在每次登陆成功后,写入session)

            User user=(User)request.getSession().getAttribute("USER");

            if(user!=null){

                return true; //向后执行

            }

            response.sendRedirect(request.getContextPath()+"你的登陆页地址");

        } catch (IOException e) {

            e.printStackTrace();

        }

        return false;//停止执行

    }

 

     // 请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)

    @Override

    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {

          // System.out.println("执行了TestInterceptorpostHandle方法");

    }

 

     // 在整个请求结束之后被调用,主要是用于进行资源清理工作

    @Override

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {

          // System.out.println("执行了TestInterceptorafterCompletion方法");

    }

    

}

 

  1. 注册拦截器,通过编写拦截器配置文件类并继承 WebMvcConfigurer类,并重写其中的方法  addInterceptors并且在主类上加上注解  @Configuration,将拦截器添加到自定义的配置类中

示例

@Configuration

public class LoginConfig implements WebMvcConfigurer {

    

    @Override

    public void addInterceptors(InterceptorRegistry registry) {

        //注册TestInterceptor拦截器

        InterceptorRegistration registration = registry.addInterceptor(new AdminInterceptor());

 

        registration.addPathPatterns("/**");                      //拦截所有路径

 

        registration.excludePathPatterns(                         //添加不拦截的静态资源

                                         "/login",            //登录界面路径

                                         "/**/*.html",            //html静态资源

                                         "/**/*.js",              //js静态资源,"/js/**"

                                         "/**/*.css",             //css静态资源,"/css/**"

                                 "/**/*.img",  

                                         "/**/*.woff",

                                         "/**/*.ttf"

                                         );    

    }

}