springmvc拦截器

慎重改动,以下文章引用本文:
https://www.malaoshi.top/show_1EFE3ahx0m1.html
https://www.malaoshi.top/show_1EF5rcqjTdOJ.html

介绍

相当于 JAVAWEB中的过滤器Filter,用于拦截请求,可以在 请求(Controller)前 和 请求(Controller)后 做其他处理

Interceptor拦截器是 链式的,可以有多个Interceptor,SpringMVC会根据添加顺序一个接一个的执行

链式的理解

相当于学校保安,大门口有保安,校园里有保安、寝室楼有保安,从大门口进寝室楼,要经过多个保安

常见应用场景

  1. 日志记录:记录请求信息的日志,以便进行 IP监控、信息统计、计算PV(Page View)等。

  2. 登录检查:检查当前请求是否已经登录,如果没有返回到登录页面;

  3. 权限检查:防止普通用户访问管理员页面

  4. 性能监控:有时系统在某段时间无原因卡顿,可以通过拦截器在请求之前记录开始时间,在处理完后记录结束时间,结束时间 减去 开始时间,就是请求的处理时间

源码分析

实现 HandlerInterceptor 接口,该接口源码如下:

jdk1.8后,接口支持 default方法:

package org.springframework.web.servlet;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.lang.Nullable;

public interface HandlerInterceptor {
    default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return true;
    }

    default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
    }

    default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
    }
}

jdk1.7前:

package org.springframework.web.servlet;  
public interface HandlerInterceptor {  
    boolean preHandle(  
            HttpServletRequest request, HttpServletResponse response,   
            Object handler)   
            throws Exception;  

    void postHandle(  
            HttpServletRequest request, HttpServletResponse response,   
            Object handler, ModelAndView modelAndView)   
            throws Exception;  

    void afterCompletion(  
            HttpServletRequest request, HttpServletResponse response,   
            Object handler, Exception ex)  
            throws Exception;  
}

执行过程

preHandle()方法

  • 在 Controller之前 执行,可以用来做一些编码处理、安全限制之类的操作。

  • 该方法返回 true ,则继续执行 Controller;返回false 表示流程中断,不会调用其他的拦截器,此时需要通过 response 产生响应。

  • 当有多个拦截器时,所有的 Interceptor 中的preHandle()方法都会在 Controller 之前调用,执行顺序:先添加的先执行

postHandle()方法

  • 在 Controller执行后,在渲染视图之前执行(在DispatcherServlet进行视图的渲染之前执行)

  • 当有多个拦截器时,所有的Interceptor中的postHandle()方法都会在 Controller 之后调用,执行顺序:先添加的后执行

  • 注意: controller抛异常时不执行此方法

afterCompletion()方法

  • 最后执行,即:在视图渲染完毕再执行。
    无论是否出错都会执行这个方法(类似于try-catch-finally中的finally),

  • 一般用于 清理资源


原文出处:/show_1EF5rYIz0e7e.html