博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

SpringMVC - 05拦截器

Posted on 2020-11-22 21:41  Kingdomer  阅读(98)  评论(0编辑  收藏  举报

SpringMVC - 05拦截器

(1)拦截器(interceptor)的作用

SpringMVC的拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理后处理

将拦截器按一定的顺序联结成一条链,这条链称为拦截器链(Interceptor Chain)
在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。拦截器也是AOP思想的具体实现。
 

(2)拦截器和过滤器的区别

区别 过滤器 拦截器
使用范围 是Servlet规范中的一部分,任何Java Web工程都可以使用 是SpringMVC框架自己的,只有使用了SpringMVC框架的工程才能使用
拦截范围 在url-pattern中配置了/*之后,可以对所有要访问的资源进行拦截 只会拦截访问的控制器方法,如果访问的是jsp/html/css/image或者js,是不会进行拦截的
 
 

 

 

 

(3)拦截器快速入门

(3.1)初始业务代码
@Controller
public class TargetController {

    @RequestMapping("/target")
    public ModelAndView show(){
        System.out.println("目标资源执行了......");
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("name","zhangsan");
        modelAndView.setViewName("index");
        return modelAndView;
    }
}

 

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>Hello world!  ${name}-${age}</h1>
</body>
</html>

(3.2)创建拦截器,实现HandlerInterceptor接口

public class MyInterceptor1 implements HandlerInterceptor {
    // 在目标方法执行前执行
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException {
        System.out.println("preHandler......");
//        return true; // 返回true 代表 放行
        String param = request.getParameter("param");
        if("yes".equals(param)){
            return true;
        }else {
            request.getRequestDispatcher("/error.jsp").forward(request,response);
            return false;
        }
    }
    // 在目标方法执行后, 视图返回之前 执行
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
        modelAndView.addObject("name","beapx");
        System.out.println("postHandle......");
    }

    // 在流程都执行完毕后执行
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        System.out.println("afterCompletion......");
    }
}

(3.3)在spring-mvc.xml配置拦截器

    <!--1. 配置MVC-->
    <mvc:annotation-driven/>

    <!--2. 配置视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <!--3. 配置静态资源权限开放-->
    <mvc:default-servlet-handler/>

    <!--4. 组件扫描 扫描controller-->
    <context:component-scan base-package="com.bearpx.spring.interceptor"></context:component-scan>
    <!-- 配置拦截器 -->
    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>    <!--对哪些资源执行拦截操作-->
            <bean class="com.bearpx.spring.interceptor.MyInterceptor1"/>
        </mvc:interceptor>
    </mvc:interceptors>

(3.4)测试

> 请求URL地址:   http://localhost:8080/target?param=yes    正常放行
preHandler......
目标资源执行了......
postHandle......
afterCompletion......

> 请求URL地址:http://localhost:8080/target?param=sss    阻断

preHandler......

(3.5) 新增一个拦截器

public class MyInterceptor2 implements HandlerInterceptor {
    // 在目标方法执行前执行
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException {
        System.out.println("preHandler222222......");
        return true; // 返回true 代表 放行
    }

    // 在目标方法执行后, 视图返回之前 执行
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
        modelAndView.addObject("age",18);
        System.out.println("postHandle22222......");
    }

    // 在流程都执行完毕后执行
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        System.out.println("afterCompletion222222......");
    }
}

 

    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="com.bearpx.spring.interceptor.MyInterceptor1"/>
        </mvc:interceptor>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="com.bearpx.spring.interceptor.MyInterceptor2"/>
        </mvc:interceptor>
    </mvc:interceptors>

(3.6)再次测试

> 请求URL地址:   http://localhost:8080/target?param=yes    正常放行
preHandler......
preHandler222222......
目标资源执行了......
postHandle22222......
postHandle......
afterCompletion222222......
afterCompletion......

 

> 请求URL地址:http://localhost:8080/target?param=sss    阻断

preHandler......

(3.7)拦截器配置顺序

    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="com.bearpx.spring.interceptor.MyInterceptor2"/>
        </mvc:interceptor>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="com.bearpx.spring.interceptor.MyInterceptor1"/>
        </mvc:interceptor>
    </mvc:interceptors>

> 请求URL地址:http://localhost:8080/target?param=sss    阻断

preHandler222222......
preHandler......
afterCompletion222222......

拦截器起作用与在配置文件中的配置顺序有关系。

(3.8)拦截器方法说明

方法名 说明
preHandle()
方法将在请求处理之前进行调用,该方法的返回值是布尔值Boolean类型的,当它返回为false时,表示请求结束,后续的Interceptor和Controller都不会再执行,
当返回值为true时就会继续调用下一个Interceptor的preHandle方法
postHandle()
该方法是在当前进行处理之后被调用,前提是preHandle方法的返回值为true时才能被调用,且它会在DispatcherServlet 进行视图返回渲染之前被调用,
所以我们可以在这个方法中对Controller处理之后的ModelAndView对象进行操作
afterCompletion()
该方法将在整个请求结束之后,也就是在DispatcherServlet渲染了对应的视图之后执行,前提是preHandle方法的返回值为true时才能被调用