目录
一、概念二、自定义拦截器的三个实现方法
三、自定义拦截器执行流程
四、使用
 五、拦截器和过滤器
一、概念
 在学习拦截器之前,我们得先了解一下它是个什么❓
 SpringMVC可以通过拦截器对请求进行拦截处理,用户可以自定义拦截器来实现特定的功能。
  如何实现自定义的拦截器❓
 自定义的拦截器必须实现HandlerInterceptor。
二、自定义拦截器的三个实现方法
- 
preHandle():这个方法在业务处理器处理请求之前被调用,在该方法中对用户请求request 进行处理。
- 
postHandle():这个方法在目标方法处理完请求后执行。
- 
afterCompletion():这个方法在完全处理完请求后被调用,可以在该方法中进行一些资源清理的操作。
到这里不知道大家有没有发现,这个SpringMVC中的拦截器和我们学Servlet时的Filter过滤器有点像。至于这个问题我们后边说到。
三、自定义拦截器执行流程图

 自定义拦截器执行流程说明:
- 如果 preHandle方法 返回 false, 则不再执行目标方法, 可以在此指定返回页面。
- 
postHandle在目标方法被执行后执行。可以在方法中访问到目标方法返回的ModelAndView 对象。
- 若preHandle返回 true, 则afterCompletion方法 在渲染视图之后被执行。
- 若preHandle返回 false, 则afterCompletion方法不会被调用。
- 在配置拦截器时,可以指定该拦截器对哪些请求生效,哪些请求不生效。
四、使用
前端
<%--
  Created by IntelliJ IDEA.
  User: huawei
  Date: 2022/11/30
  Time: 21:42
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>测试自定义拦截器</title>
</head>
<body>
<h1>测试自定义拦截器</h1>
<a href="<%=request.getContextPath()%>/hi">测试拦截器</a>
<a href="<%=request.getContextPath()%>/hello">测试拦截器</a>
</body>
</html>后端
拦截器1
package com.jl.web.interceptor;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * ClassName: MyInterceptor
 * Package: com.jl.web.interceptor
 * Description: 演示自定义拦截器
 *
 * @Author: Long
 * @Create: 2022/11/30 - 21:32
 * @Version: v1.0
 */
@Component
public class MyInterceptor01 implements HandlerInterceptor {
    /**
     * 该方法在目标方法执行前执行,如果该方法返回false,就不再执行目标方法
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("MyInterception01----preHandle");
        return true;
    }
    /**
     * 在目标方法执行后会执行该方法
     * 该方法可以获取到 目标方法返回的 ModelAndView
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("MyInterception----postHandle");
    }
    /**
     * 在视图渲染后执行
     * 在这里可以做一些资源清理工作
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("MyInterception----afterCompletion");
    }
}拦截器2
package com.jl.web.interceptor;
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;
/**
 * ClassName: MyInterception
 * Package: com.jl.web.interceptor
 * Description:
 *
 * @Author: Long
 * @Create: 2022/11/30 - 22:13
 * @Version: v1.0
 */
@Component
public class MyInterceptor02 implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("-----MyInterception02----preHandle");
        return true;
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("-----MyInterception02----postHandle");
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("-----MyInterception02----afterCompletion");
    }
}请求的目标Handler
package com.jl.web.interceptor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
 * ClassName: FurnHandler
 * Package: com.jl.web.interceptor
 * Description:
 *
 * @Author: Long
 * @Create: 2022/11/30 - 21:40
 * @Version: v1.0
 */
@Controller
public class FurnHandler {
    @RequestMapping(value = "/hi")
    public String hi(){
        System.out.println("----FurnHandler---hi");
        return "success";
    }
    @RequestMapping(value = "/hello")
    public String hello(){
        System.out.println("----FurnHandler---hello");
        return "success";
    }
}我们的Handler中提供了两个处理方法。
配置自定义拦截器
<!--配置自定义拦截器-->
  <mvc:interceptors>
      <!--第一种配置方式
          直接使用 ref 引用到对应的 myInterceptor01
          这种方式会拦截所有的目标方法
      -->
      <!--<ref bean="myInterceptor01"/>-->
      <!--第二种配置方式
          mvc:mapping path="/hi/" 指定要拦截的路径
          ref bean="myInterceptor01" 指定对哪个拦截器进行配置
      -->
      <!--<mvc:interceptor>-->
      <!--    <mvc:mapping path="/hi"/>-->
      <!--    <ref bean="myInterceptor01"/>-->
      <!--</mvc:interceptor>-->
      <!--第三种配置方式
          支持通配符
          <mvc:mapping path="/h*"/> h开头的目标方法全部拦截
          <mvc:exclude-mapping path="/hello"/> 不拦截 /hello 路径
      -->
      <mvc:interceptor>
          <mvc:mapping path="/h*"/>
          <mvc:exclude-mapping path="/hello"/>
          <ref bean="myInterceptor01"/>
      </mvc:interceptor>
      <!--配置第二个拦截器
            当有多个拦截器,是按照配置顺序来执行的
      -->
      <mvc:interceptor>
          <mvc:mapping path="/h*"/>
          <ref bean="myInterceptor02"/>
      </mvc:interceptor>
  </mvc:interceptors>我们这种配置是:拦截器1只拦截hi,而拦截器2hi和hello都拦截。
下边我们看一下结果:

 请求hi两个拦截器都生效。

请求hello只有拦截器2生效。
五、拦截器和过滤器

 
 
                     
            
        













 
                    

 
                 
                    