spring mvc 拦截器 配置及应用

spring mvc 中的拦截器

拦截器和过滤器的作用是相同的,都是要把不符合情况的代码给拦截或者可以说是过滤掉,如:登录的密码或用户名不符合时,不可以登录等,这些都是需要被拦截或者过滤的。

1)编写拦截器(实现 HandlerInterceptor 接口) 

@Component
public class Interceptor1 implements HandlerInterceptor {

    // 在控制器方法执行前被调用, 返回 true 放行请求, 如果返回 false 拦截请求(不会前进了)
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //代码
        return true|false;
    }

    // 在控制器方法执行后被调用
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        //代码
    }

    // 在控制器和视图都完成后被调用
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        //代码
    }
}

2)配置拦截器

<!-- 某个拦截器 -->
<mvc:interceptor>
    <!-- 拦截器要匹配的路径 如:/hello -->
    <mvc:mapping path="路径" />

    <!-- 要调用的拦截器的名字,也就是实现 HandlerInterceptor 接口的类 -->
    <ref bean="拦截器名"/>
</mvc:interceptor>
  •  * 表示只能匹配一层地址,如:/user/insert,不能是 /user/mvc/insert
  • ** 表示多层地址,如:/user/insert  和 /user/mvc/insert 都行

代码演示

1、拦截器演示

springmvc.xml 里拦截器的配置如下:

<!-- 扫描拦截器 -->
    <context:component-scan base-package="com.westos.interceptor"/>
    <!-- 配置 要拦截哪些控制器 -->
    <mvc:interceptors>
        <!-- 某个拦截器 -->
        <mvc:interceptor>
            <!--
                /* 只能匹配一层
                /user/insert
                /user/update
                /user/delete

                不能匹配
                /user/abc/insert

                /** 匹配任意层
            -->
            <mvc:mapping path="/user/**" />
            <!-- bean ="bean的id" -->
            <ref bean="interceptor1"/>
        </mvc:interceptor>

        <mvc:interceptor>
            <mvc:mapping path="/user/**"/>
            <ref bean="interceptor2"/>
        </mvc:interceptor>


    </mvc:interceptors>

 HelloController类 控制器,用来使拦截器的调用方法突出而设置的

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class HelloController {

    @RequestMapping("/user/insert")
    public String insert() {
        System.out.println("进入了 insert 方法");
        //跳转到hello.jsp页面
        return "hello";
    }

    @RequestMapping("/user/update")
    public String update() {
        System.out.println("进入了 update 方法");
        return "hello";
    }

    @RequestMapping("/user/detail/insert")
    public String dinsert() {
        System.out.println("进入了 detail/insert 方法");
        return "hello";
    }
}

hello.jsp页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
hello.jsp
</body>
</html>
<%--为了看出拦截器的 afterCompletion 方法会在在控制器和视图都完成后被调用 故意设置此输出--%>
<%
System.out.println("jsp 执行完毕");
%>

拦截器1

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

//有了Component 就不需要配置bean了,interceptor1 以当前类名字首字母小写作为 bean 的id
@Component
public class Interceptor1 implements HandlerInterceptor {

    // 在控制器方法执行前被调用, 返回 true 放行请求, 如果返回 false 拦截请求(不会前进了)
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("==========> 进入了 Interceptor1 preHandle");
        return true;
    }

    // 在控制器方法执行后被调用
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("==========> 进入了 Interceptor1 postHandle");
    }

    // 在控制器和视图都完成后被调用
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("==========> 进入了 Interceptor1 afterCompletion");
    }
}

拦截器2

@Component
public class Interceptor2 implements HandlerInterceptor {

    // 在控制器方法执行前被调用, 返回 true 放行请求, 如果返回 false 拦截请求(不会前进了)
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("==========> 进入了 Interceptor2 preHandle");
        return true;
    }

    // 在控制器方法执行后被调用
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("==========> 进入了 Interceptor2 postHandle");
    }

    // 在控制器和视图都完成后被调用
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("==========> 进入了 Interceptor2 afterCompletion");
    }
}

结果

hello.jsp页面,以上 HelloController类中的方法成功执行,都会跳转到该页面:

当地址栏输入 http://localhost:8080/user/insert 时,结果如下:

==========> 进入了 Interceptor1 preHandle
==========> 进入了 Interceptor2 preHandle
进入了 insert 方法
==========> 进入了 Interceptor2 postHandle
==========> 进入了 Interceptor1 postHandle
jsp 执行完毕
==========> 进入了 Interceptor2 afterCompletion
==========> 进入了 Interceptor1 afterCompletion

当地址栏输入 http://localhost:8080/user/update 时,结果如下:

==========> 进入了 Interceptor1 preHandle
==========> 进入了 Interceptor2 preHandle
进入了 update 方法
==========> 进入了 Interceptor2 postHandle
==========> 进入了 Interceptor1 postHandle
jsp 执行完毕
==========> 进入了 Interceptor2 afterCompletion
==========> 进入了 Interceptor1 afterCompletion

当地址栏输入 http://localhost:8080/user/detail/insert 时,结果如下:

==========> 进入了 Interceptor1 preHandle
==========> 进入了 Interceptor2 preHandle
进入了 detail/insert 方法
==========> 进入了 Interceptor2 postHandle
==========> 进入了 Interceptor1 postHandle
jsp 执行完毕
==========> 进入了 Interceptor2 afterCompletion
==========> 进入了 Interceptor1 afterCompletion

从以上结果可以看出拦截器的 preHandle 方法是调用在控制器方法之前,postHandle 是在之后,afterCompletion 是在控制器和视图之后调用的,后面调用的 postHandle 和 afterCompletion 调用方法的顺序是和 preHandle 相反的,这里有一点要注意,那就是配置 springmvc.xml 中的拦截器配置时,如果把拦截器1和拦截器2位置颠倒,那么会先进入拦截器1,然后在进入拦截器2,如:进入 http://localhost:8080/user/detail/insert 时,结果如下:

==========> 进入了 Interceptor2 preHandle
==========> 进入了 Interceptor1 preHandle
进入了 detail/insert 方法
==========> 进入了 Interceptor1 postHandle
==========> 进入了 Interceptor2 postHandle
jsp 执行完毕
==========> 进入了 Interceptor1 afterCompletion
==========> 进入了 Interceptor2 afterCompletion

猜你喜欢

转载自blog.csdn.net/grey_mouse/article/details/87931573