1

初步认识SpringMVC拦截器

什么是拦截器

拦截器是指通过统一拦截从浏览器发往服务器的请求来完成功能的增强
使用场景:解决请求的共性问题(如:乱码问题、权限验证问题等)

拦截器的实现

创建一个拦截器的类,且让其实现HandlerInterceptor接口。使请求在到达控制器之前都先经过它。
2020-03-02-17-21-08.png

public class TokenInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        return false;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }
}

将拦截器注册进SpringMVC的配置文件中并配置拦截器的拦截规则。

<!-- 注册一个拦截器 所有请求都会经过-->
<mvc:interceptors>
    <bean class="com.mmall.interceptor.TokenInterceptor"></bean>
</mvc:interceptors>
<!-- 注册多个拦截器 指定路径会经过-->
<mvc:interceptors>
    <!-- 配置一个全局拦截器,拦截所有请求 -->
    <bean class="com.mmall.interceptor.TokenInterceptor" /> 
    <mvc:interceptor>
        <!-- 配置拦截器作用的路径 -->
        <mvc:mapping path="/**" />
        <!-- 配置不需要拦截作用的路径 -->
        <mvc:exclude-mapping path="" />
        <!-- 定义<mvc:interceptor>元素中,表示匹配指定路径的请求才进行拦截 -->
        <bean class="com.mmall.interceptor.TokenInterceptor"></bean>
    </mvc:interceptor>
    <mvc:interceptor>
        <mvc:mapping path="/user/*.do"/>
        <bean class="com.mmall.interceptor.TokenInterceptor1"></bean>
    </mvc:interceptor>
</mvc:interceptors>

在上述示例代码中需要注意:

  • <mvc:interceptors>元素用于配置一组拦截器,其子元素 <bean> 定义的是全局拦截器,即拦截所有的请求。
  • <mvc:interceptor>元素中定义的是指定路径的拦截器,其子元素 <mvc:mapping> 用于配置拦截器作用的路径,该路径在其属性 path 中定义。
  • path的属性值/**表示拦截所有路径,/gotoTest表示拦截所有以/gotoTest结尾的路径。如果在请求路径中包含不需要拦截的内容,可以通过 <mvc:exclude-mapping> 子元素进行配置。
  • <mvc:interceptor> 元素的子元素必须按照 <mvc:mapping.../><mvc:exclude-mapping.../><bean.../> 的顺序配置。

拦截器的方法介绍

1、preHandle方法,在请求被处理之前进行调用

  • 可以看到值有preHandle方法有一个布尔类型的返回值

    • 返回值为true时:请求会被继续运行
    • 返回值为false时:请求将被停止
  • HttpServletRequest:包含所有请求的内容
  • HttpServletRequest:包含所有响应的内容
  • Object o 参数:被拦截的请求的目标对象(包含控制器中的名称等信息)
  • 应用场景:身份认证、身份授权

2、postHandle方法,在请求被处理之后进行调用

  • modelAndView参数:可以通过该参数来改变显示的视图,或修改发往视图的方法
  • 应用场景:从modelAndView出发,将公用的模型数据(比如菜单导航)在这里传到视图,也可以在这里统一指定视图

3、afterCompletion方法,在请求结束之后才进行调用,类似析构方法(比较少用)

  • 应用场景:统一异常处理,统一日志处理

多个拦截器的应用

多个拦截器协同时工作流程图:
2020-03-02-17-42-36.png

<!--多个拦截器,顺序执行 -->
<mvc:interceptors>
    <!-- 登陆认证拦截器 -->
    <mvc:interceptor>
        <mvc:mapping path="/**"/>
        <bean class="cn.itcast.ssm.interceptor.LoginInterceptor"></bean>
    </mvc:interceptor>
    <mvc:interceptor>
        <!-- 表示所有url包括子url路径 -->
        <mvc:mapping path="/**"/>
        <bean class="cn.itcast.ssm.interceptor.HandlerInterceptor1"></bean>
    </mvc:interceptor>
    <mvc:interceptor>
        <mvc:mapping path="/**"/>
        <bean class="cn.itcast.ssm.interceptor.HandlerInterceptor2"></bean>
    </mvc:interceptor>
</mvc:interceptors>

拦截器的其他实现方式

实现WebRequestInterceptor接口

public class TokenInterceptor1 implements WebRequestInterceptor {

    @Override
    public void preHandle(WebRequest webRequest) throws Exception {
        
    }

    @Override
    public void postHandle(WebRequest webRequest, ModelMap modelMap) throws Exception {

    }

    @Override
    public void afterCompletion(WebRequest webRequest, Exception e) throws Exception {

    }
}

与HandlerInterceptor的区别:

  • 参数名变了
  • 无法通过preHandle方法来终止请求
  • 使用起来大同小异

拦截器的使用例子

public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
    // 在此可以写判断是否登录的逻辑
    if(httpServletRequest.getHeader("token")!="123"){
        // 登录验证失败 转发到其他的接口上
        httpServletResponse.sendRedirect("/user/not_login.do");
        // 终止请求
        return false;
    }
    return true;
}

拦截器的对比和总结

拦截器的工作原理和过滤器非常相似。
过滤器Filter依赖于Servlet容器,基于回调函数,过滤范围大。
拦截器Interceptor依赖于框架容器,基于反射机制,只过滤请求。
拦截器可以处理Web应用中请求的一些通用性问题、共性问题在拦截器中处理,可以减少重复代码,便于维护。

学习来源:
https://www.imooc.com/learn/498
https://www.cnblogs.com/ustc-...
http://c.biancheng.net/view/4...


smartboy
16 声望3 粉丝

您好,世界!