1.  拦截器就是动态的实现拦截Action调用的对象.他提供了一种机制可以使开发者可以定义在一个action 执行的前后的执行代码,也可以在一个action执行之前阻止其执行;
  2. 在AOP中拦截器用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作;拦截器是AOP的一种实现;
  3. 很多时候,拦截器都是通过代理的方式来调用的,Struts2也有拦截器.只是其实现相对简单,他是在当请求发送到Struts 2 的DispatcherServlet 时,Struts 2会查找配置文件,并根据其配置实例化相对的拦截器对象,组成一个列表,最后调用表中的拦截器;

拦截器与过滤器的区别:

  • 拦截器是SpringMVC框架自己的,只有在使用了SpringMVC的框架才可以使用拦截器;
  • interceptor 只会拦截控制器(controller)中的方法,如果访问的是资源文件或者页面,interceptor将不会有任何的作用;
  • interceptor是基于java反射机制的,而过滤器是基于函数回调的;
  • 过滤器依赖一servlet容器,而interceptor则不依赖;
  • interceptor 只会对 action 起作用,而过滤器几乎可以对所有的请求发挥作用;
  • interceptor可以访问 action 上下文,以及栈的对象,但是过滤器则不能;
  • interceptor 可以进行多次的调用,但是过滤器只能在程序启动时过滤一次;

如何自定义一个拦截器:

自定义一个拦截器只需以下三步即可:

  1. 自定义实现一个 interceptor 接口(或者继承了abstractinterceptor)的类;
  2. 配置文件,配置拦截器,及拦截的内容;
  3. 在需要使用的Action中引用上述定义的拦截器,为了方便也可将拦截器定义为默认的拦截器,这样在不加特殊声明的情况下所有的Action都被这个拦截器拦截。

1.自定义实现一个interceptor的接口

package com.zhang.interceptor;

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

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

public class MyInterceptor implements HandlerInterceptor {
    /*
    interceptor在请求处理的方法之前执行;
    如果返回的是true,执行下一个拦截器;
    如果返回的是false,就不执行下一个拦截器;
     */
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        System.out.println("========处理前=======");
        return true;
    }

    //在请求处理方法执行之后执行
    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        System.out.println("========处理后=======");
    }

    //在DispatcherServlet执行后处理,做清理工作;
    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        System.out.println("========清理=======");
    }
}

2.编写配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd">


    <context:component-scan base-package="com.zhang.controller"/>
    <!--静态资源过滤:Spring不处理静态资源,html,js,css,jpg,....-->
    <mvc:default-servlet-handler/>
    <mvc:annotation-driven/>

    <!--配置拦截器interceptors,复数,可以配置多个拦截器-->
    <mvc:interceptors>
        <mvc:interceptor>
            <!--/** 包括路径及其子路径-->
            <!--/admin/* 拦截的是/admin/所请求的当前路径不会拦截器子请求-->
            <!--/admin/** 拦截的是/admin/下的所有-->
            <mvc:mapping path="/**"/>
            <!--拦截器的bean-->
            <bean class="com.zhang.interceptor.MyInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>
</beans>

 3.index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<a href="${pageContext.request.contextPath}/Test1">拦截测试</a>
</form>
</body>
</html>

4.编写Controller类

package com.zhang.controller;

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

@Controller
public class InterceptorController {
    @RequestMapping("/Test1")
    @ResponseBody
    public String Test1() {
        System.out.println("控制器中的方法执行了");
        return "good";
    }
}

5.以上代码编译运行的结果如下图所示:

拦截器(Interceptor)_拦截器

实例:认证用户登录问题

实现步骤:

  1. 设置一个登录页面,编写controller访问页面;
  2. 在登录页面提交表单后,需要在controller类中处理,对用户进行判断,如果是用户名和密码都是正确的,则向session会话中写入用户信息,再返回登录成功;
  3. 拦截用户请求,对用户是否登录进行判断;如果用户登录成功,就通过,否则返回登录页面;

 编写controller类

package com.zhang.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpSession;

@Controller
@RequestMapping("/user")
public class UseController {
    //跳转到登陆页面
    @RequestMapping("/tologin")
    public String Tologin(){
        return "login";
    }

    //跳转到成功页面
    @RequestMapping("/tosuccess")
    public String tosuccess(){
        return "success";
    }

    //登录提交
    @RequestMapping("/login")
    public String login(HttpSession session,String username,String pwd){
        //向session记录用户信息
        System.out.println("接收前端"+username);
        session.setAttribute("user",username);
        return "success";
    }

    //退出登录
    @RequestMapping("/logout")
    public String logout(HttpSession session){
        //session过期
        session.invalidate();
        return "login";
    }
}

编写拦截器:

package com.zhang.interceptor;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class UseInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //如果是登录页面就放行
        System.out.println("uri"+ request.getRequestURI());
        if (request.getRequestURI().contains("login")){
            return  true;
        }

        HttpSession session = request.getSession();
        //如果用户已经登录也放行
        if (session.getAttribute("user")!=null){
            return true;
        }
        //如果用户没有登录调到登录页面
        request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request,response);
        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 {
    }
}

编写配置文件:

<mvc:interceptor>
            <mvc:mapping path="/**"/>
            <!--拦截器的bean-->
            <bean id="useInterceptor" class="com.zhang.interceptor.UseInterceptor"/>
 </mvc:interceptor>

编写登录页面:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登录</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/user/login">
    用户名:<input type="text" name="username"><br>
    密码:<input type="password" name="pwd"><br>
    <input type="submit" value="提交">
</form>
</body>
</html>

编写成功页面:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>注销</title>
</head>
<body>
${user}
<a href="${pageContext.request.contextPath}/user/logout">注销</a>
</form>
</body>
</html>

编写前端页面:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<%--登录--%>
<a href="${pageContext.request.contextPath}/user/tologin">登录</a>
<a href="${pageContext.request.contextPath}/user/tosuccess">成功页面</a>
</body>
</html>

测试:

登录页面

拦截器(Interceptor)_mvc_02

登录成功的页面 

拦截器(Interceptor)_拦截器_03

以上代码编译运行的过程如下图所示:

拦截器(Interceptor)_拦截器_04

测试拦截OK;