SpringMVC中的拦截器Interceptor

拦截器的使用

1、拦截器的使用时机

SpringMVC中提供了一个拦截器Interceptor,其功能类似于Servlet中的过滤器Filter,但是拦截器只能拦截请求,并不能拦截响应。常用拦截器进行用户的权限验证,以及判断用户是否登录系统,未登录的进行拦截等。当你需要对用户的某些请求进行拦截时,比如非法请求,那么就可以使用拦截器来实现。

2、拦截器的原理

SpringMVC中提供了拦截器HandlerInterceptor的接口,先看这个接口源码。

org.springframework.web.servlet.HandlerInterceptor接口的源码:
SpringMVC中的拦截器Interceptor
SpringMVC中的拦截器Interceptor
SpringMVC中的拦截器Interceptor
只提供了3个方法:preHandle、postHandle、afterCompletion。这三个方法的说明如下:

  • preHandle方法:该方法会在控制器方法之前执行,其返回值表示是否中断后续操作。当其返回值为true时,表示继续向下执行;当其返回值为false时,会中断后续的所有操作(包括调用下一个拦截器和控制器类中的方法执行等)。

  • postHandle方法:该方法会在控制器方法调用之后,并且在解析视图之前执行。可以通过此方法对请求域中的模型和视图做出进一步的修改。

  • afterCompletion方法:该方法会在整个请求完成,即视图渲染结束之后执行。可以通过此方法实现一些资源清理、记录日志信息等工作。

图示:
SpringMVC中的拦截器Interceptor
如果配置了拦截器,那么一个请求到达服务端之后,服务端会先执行拦截器的preHandle方法,然后执行控制器中的业务方法,然后执行拦截器的postHandle方法,然后再执行视图渲染操作,渲染完毕返回视图之后,最后执行拦截器的afterCompletion方法。

3、拦截器的使用

要想使用SpringMVC提供的拦截器,一般做法是定义一个类直接实现HandlerInterceptor接口,或者是直接继承HandlerInterceptor接口的实现类。这里就直接实现接口了。

/*
 * 这个类作为拦截器使用
 */
public class MyInterceptor implements HandlerInterceptor {

    // 这个方法在视图渲染之后执行
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        System.out.println("执行afterCompletion方法!");
    }

    // 这个方法在控制器业务方法执行之后且渲染视图之前执行
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        System.out.println("执行postHandle方法!");
    }

    // 这个方法在控制器业务方法执行前执行
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        System.out.println("执行preHandle方法!");
        return true;
    }

}

然后需要在springMVC配置文件中配置这个拦截器:
SpringMVC中的拦截器Interceptor
控制器:
SpringMVC中的拦截器Interceptor
测试:
SpringMVC中的拦截器Interceptor
从控制台输出可以看到执行顺序。然后再定义一个拦截器:

/*
 * 这个类作为拦截器使用
 */
public class MyInterceptor2 implements HandlerInterceptor {

    // 这个方法在视图渲染之后执行
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        System.out.println("执行afterCompletion222方法!");
    }

    // 这个方法在控制器业务方法执行之后且渲染视图之前执行
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        System.out.println("执行postHandle222方法!");
    }

    // 这个方法在控制器业务方法执行前执行
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        System.out.println("执行preHandle222方法!");
        return true;
    }

}

修改之前的拦截器:
SpringMVC中的拦截器Interceptor
配置拦截器:
SpringMVC中的拦截器Interceptor
测试:
SpringMVC中的拦截器Interceptor
可以看到如果先执行拦截器1的preHandle方法再执行拦截器2的preHandle方法,那么就会先执行拦截器2的postHandle方法再执行拦截器1的,先执行拦截2的afterCompletion方法再执行拦截器1的,配置多个拦截器时注意各个拦截器方法的执行顺序,这点很重要。

4、测试拦截器Intercaptor和过滤器Filter

使用SpringMVC提供的拦截器Intercaptor和Servlet提供的过滤器Filter都可以对用户的请求进行拦截处理,下面测试一下如果同时配置了Filter和Interceptor的话,执行顺序是怎样的。

定义一个过滤器:

public class MyFilter implements Filter{

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("过滤器初始化!");    
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        System.out.println("过滤器进行过滤......");
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
        System.out.println("过滤器销毁!");    
    }

}

配置过滤器:
SpringMVC中的拦截器Interceptor
测试:
SpringMVC中的拦截器Interceptor
SpringMVC中的拦截器Interceptor
结论:过滤器在web应用启动时完成初始化,启动之后,用户请求先经过过滤器Filter进行过滤,然后再经过拦截器Interceptor。

上一篇:小程序入门学习Demo


下一篇:微信扫一扫不能打开APK下载链接 微信屏蔽网页跳转到app store的解决办法