统一功能处理(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)统一数据返回格式

相关推荐
zihan03214 小时前
若依(RuoYi)框架升级适配 JDK 21 和 SpringBoot 3.5.10
java·spring boot·spring·若依·若依升级jdk21
Coder_Boy_5 小时前
以厨房连锁故事为引,梳理Java后端全技术脉络(JVM到云原生,总结篇)
java·jvm·spring boot·分布式·spring·云原生
Drifter_yh13 小时前
【黑马点评】Redisson 分布式锁核心原理剖析
java·数据库·redis·分布式·spring·缓存
莫寒清14 小时前
Spring MVC:@RequestParam 注解详解
java·spring·mvc
♡喜欢做梦17 小时前
Spring Boot 日志实战:级别、持久化与 SLF4J 配置全指南
java·spring boot·后端·spring·java-ee·log4j
玹外之音1 天前
告别 STDIO/SSE:Spring AI Streamable HTTP MCP 实战指南
后端·spring
番茄去哪了1 天前
苍穹外卖day07---Redis缓存优化与购物车功能实现
java·数据库·ide·spring boot·spring·maven·mybatis
Dragon Wu1 天前
SpringCache 缓存使用总结
spring boot·后端·spring·缓存·springcloud
春和景明3601 天前
springboot
spring boot·spring