统一功能处理(1)拦截器

统一功能处理(1)拦截器

文章目录

观前提醒:

如果你是第一次点击这篇博客的,需要你将我 图书管理系统 的博客列表中,从这篇开始看:
图书管理系统(1)项目准备,用户登录接口,添加图书接口

直到看到 图书管理系统(6)强制登陆前端 这篇博客。

当然,如果你只是想单纯了解 拦截器 的使用,这篇博客,也是完全可以的。

就算你不看上面的博客,也是可以的。

引入上面的博客链接,只是为了更好的展开学习 拦截器 的目的。

在图书管理系统中,我们完成了强制登录的功能,后端程序根据Session来判断用户是否登录,但是实现方法是比较麻烦的

  • 需要修改每个接口的处理逻辑
  • 需要修改每个接口的返回结果
  • 接口定义修改,前端代码也需要跟着修改

有没有更简单的办法,统⼀拦截所有的请求,并进行Session校验呢?

这⾥我们学习⼀种新的解决办法: 拦截器

1. 什么是拦截器

拦截器是Spring框架提供的核心功能之⼀,主要用来拦截用户的请求,在指定方法前后,根据业务需要执行预先设定的代码。

举例理解:

第一个例子:学校门口,保安,人脸识别

现在的大学,门口都是一个用来人脸识别的门,验证学生的身份是否是本校学生。

门口还有 保安,如果是外校学生进来本学校,就会先审问这个外校学生的信息,提供身份信息,保安判断无误,外校学生填写登记表格,才能进入这个学校。

学生回学校上课,学生回学校住宿,进入学校的前提 是:通过人脸识别的认证,确定是本校学生。

该校学生带朋友(外校学生),进学校参观,进入学校的前提 是:保安确认身份信息,登录来访记录,外校学生才能进入学校。

那么,进入学校之前的操作:保安的检验,人脸识别的检验 ,就可以认为起到了 拦截器 的作用。

如果要进校园(指定方法),就需要通过 保安的检验或人脸识别的检验(需要执行预先设定的代码),这就是拦截器的作用。

第二个例子:银行办理业务

比如我们去银行办理业务,在办理业务前后,就可以加⼀些拦截操作

办理业务之前,先取号,如果带⾝份证了就取号成功

业务办理结束,给业务办理人员的服务进行评价。

这些就是"拦截器"做的⼯作。

实际的拦截器:

拦截器 ,允许开发人员提前预定义⼀些逻辑,在用户的请求响应前后执行, 也可以在用户请求前阻⽌其执行

在拦截器当中,开发人员可以在应用程序中做⼀些通用性的操作,比如通过拦截器来拦截前端发来的请求,判断Session中是否有登录用户的信息:

如果有就可以放行。

如果没有就进行拦截。

2. 拦截器的基本使用

拦截器的使用步骤分为两步:

  1. 定义拦截器
  2. 注册配置拦截器

拦截器的代码,写在 图书管理系统(6)强制登陆前端 上,因为要和接口进行一起测试,才能看到效果

定义拦截器:

创建一个 intercepter包,里面定义 LoginIntercepter类。

实现 HandlerInterceptor接口,并重写其所有方法

代码:

java 复制代码
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

@Slf4j
@Component
public class LoginIntercepter implements HandlerInterceptor {

    /**
     *
     * @param request
     * @param response
     * @param handler
     * @return
     * true:对目标方法放行,不会拦截
     * false:拦截目标方法,通过验证之后,才能访问
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request,HttpServletResponse response,Object handler) throws Exception {
        log.info("preHandle方法,目标方法执行前。。。");

//        true: 放行目标方法
//        false:拦截目标方法
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request,HttpServletResponse response,Object handler,ModelAndView modelAndView) throws Exception {
        log.info("postHandle方法,目标方法执行后!!!");
        HandlerInterceptor.super.postHandle(request,response,handler,modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request,HttpServletResponse response,Object handler,Exception ex) throws Exception {
        log.info("LoginInterceptor 视图渲染完毕后执行,最后执行");
        HandlerInterceptor.super.afterCompletion(request,response,handler,ex);
    }
}

HandlerInterceptor 接口包含三个方法:

  • preHandle() :在目标方法执行前 调用。
    • 返回 true:放行,允许访问目标方法
    • 返回 false:拦截,阻止访问目标方法
  • postHandle() :在目标方法执行后、视图渲染前调用
  • afterCompletion() :在视图渲染完毕后执行,是整个请求处理流程的最后一步(后端开发目前一般不涉及视图,可暂不深入)

注册配置拦截器:

创建一个 config包,定义一个 WebConfig类。

实现WebMvcConfigurer接口,并重写addInterceptors方法。

代码:

java 复制代码
import lombok.extern.slf4j.Slf4j;
import org.example.book_system_20251107.book.intercepter.LoginIntercepter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Slf4j
@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Autowired
    private LoginIntercepter loginIntercepter;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        log.info("拦截器启动拦截");
        registry.addInterceptor(loginIntercepter).addPathPatterns("/**");
//        这句代码做了两件事情:
//        1. 添加拦截器对象,指定使用的拦截器
//        2.  设置拦截器拦截的请求路径( /** 表⽰拦截所 有请求)
    }
}

一定要注意的点:WebConfig类,需要添加 @Configuration注解,WebConfig类中的 addInterceptors方法,才会执行。

换句话说:WebConfig类,需要添加 @Configuration注解,拦截器才会启动

关于拦截路径:这是⼀些常见拦截路径设置:

/**:表示所有的请求路径,都会被拦截。

/book/** :表示请求路径中,包含 book 这个字符的所有请求,都会被拦截

测试:

启动图书管理系统,使用 Postman进行测试:

访问登录的接口,url= http://127.0.0.1:8080/user/login name=admin&password=admin

这是图书管理系统中,用户登录接口的路径。

preHandle()方法的返回值是:true(放行)

preHandle()方法的返回值是:false(拦截)

可以看到,这次的请求,被拦截器拦截了,没有执行之后的任何操作。

没有进行登录的验证,就是被拦截了,这次的请求,没有放行。

所以,在拦截器中,需要设置一些业务逻辑,判断请求拦截的条件。

什么情况下,应该拦截。

排除拦截请求:

拦截器,还可以排除相关路径的请求。

这个功能,在 图书管理系统(7)完善强制登录功能 中使用,并进行了演示。

3. 拦截器执行流程

正常的调用顺序:

有了拦截器之后,会在调用 Controller 之前进行相应的业务处理,执行的流程如下图:

  1. 添加拦截器后,执行Controller的方法之前,请求会先被拦截器拦截住
    执行 preHandle() 方法, 这个方法需要返回⼀个布尔类型的值:

    ​如果返回true ,就表示放行本次操作,继续访问controller中的方法

    如果返回false ,则不会放行(controller中的方法也不会执行)

  2. controller当中的方法执行完毕后,再回过来执行 postHandle() 这个方法以及afterCompletion() 方法,执行完毕之后,最终给浏览器响应数据.

    请求和响应,在有拦截器(interceptor),过滤器(filter)的时候,执行的先后顺序是这样的:

4. 总结:

这篇博客,主要讲了拦截器相关知识,主要有:

  1. 什么是拦截器
  2. 拦截器的基本使用
  3. 拦截器执行流程

最后,如果这篇博客能帮到你的,请你点点赞,有写错了,写的不好的,欢迎评论指出,谢谢!

下一篇博客:统一功能处理(2)统一数据返回格式

相关推荐
小旭952711 小时前
Spring AI Alibaba 从入门到实战:一站式掌握企业级 AI 应用开发
java·人工智能·spring
云烟成雨TD12 小时前
Spring AI 1.x 系列【50】可观测性:接入 Prometheus + Grafana
人工智能·spring·prometheus
phltxy14 小时前
MCP 从协议到 Spring AI 实战
人工智能·spring·oracle
Volunteer Technology16 小时前
SpringSecurity请求流转的本质
java·spring
云烟成雨TD17 小时前
Spring AI 1.x 系列【42】MCP 服务端 Spring Boot 启动器
java·人工智能·spring
云烟成雨TD17 小时前
Spring AI 1.x 系列【38】模型上下文协议(MCP)
java·人工智能·spring
Alson_Code17 小时前
Spring AI-1.1.0
java·人工智能·后端·spring·ai编程
小小放舟、17 小时前
@JsonCreator 注解详解——从枚举反序列化说起
spring boot·spring·spring cloud·java-ee·maven·intellij-idea·状态模式
摇滚侠20 小时前
Spring 零基础入门到进阶 入门 06-10
java·spring·intellij-idea
總鑽風21 小时前
Spring AI实战:快速集成阿里通义千问
java·后端·spring·ai编程