Java Spring Boot 如何做拦截器

在日常开发中,我们经常需要对用户的请求做一些提前处理——比如检查登录状态、统计接口响应时长、过滤敏感关键词。如果每个接口都单独写这些逻辑,不仅代码冗余,后期维护也麻烦。这时候,用拦截器就能把这些“公共动作”抽出来,像个“门卫”一样,在请求到达目标接口前或者响应返回后,统一做处理,而Java的Spring Boot框架,实现这个功能特别简单。

第一步:先写一个拦截器类

拦截器的核心是一个普通的Java类,只要实现Spring Boot提供的HandlerInterceptor接口就行,就像给“门卫”定下要做的事。这个接口里有三个常用方法:

Java Spring Boot 如何做拦截器

  • preHandle:请求到达接口之前执行,最常用,比如这里可以检查用户有没有登录;
  • postHandle:请求处理完、返回给用户之前执行,适合改返回数据;
  • afterCompletion:整个请求结束后执行,比如统计接口耗时。

举个生活化的例子:你家小区的门禁(拦截器),在你进单元门(请求接口)之前,先刷门禁卡(preHandle查登录),如果你没卡,就直接不让进(返回错误);如果你有卡,就让你进,等你到家门口(请求处理完),门禁可以记录你今天回家的时间(postHandle);等你开门进屋(请求完全结束),门禁再统计今天小区的人流量(afterCompletion)。

我们先写个简化版的登录检查拦截器:

`java

import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

public class LoginCheckInterceptor implements HandlerInterceptor {

@Override

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

// 从请求里拿用户的登录凭证,比如Session里的用户信息

Object user = request.getSession().getAttribute("loginUser");

// 如果没找到,就返回错误,不让进,返回false就拦截

if (user == null) {

response.setContentType("application/json;charset=utf-8");

response.getWriter().write("请先登录");

return false;

}

// 有用户就放行,返回true

return true;

}

}

`

第二步:把拦截器“注册”到Spring Boot里

写好拦截器类只是造好了“门卫”,还得告诉Spring Boot,这个门卫要在哪些地方干活,这一步叫“配置拦截规则”。我们需要写一个配置类,实现WebMvcConfigurer接口,重写addInterceptors方法,把刚才写的拦截器加进去,再指定拦截的路径。

还是用小区的例子:不能让门禁管小区所有地方吧?比如快递柜、健身区就不用刷门禁,只有单元楼的门需要。对应到开发里,就是要设置哪些请求走拦截器,哪些不用。比如我们要拦截所有以/api/开头的接口,但是/api/user/login(登录接口)不用拦截,因为没登录的时候得能登进去。

配置类的代码如下:

`java

import org.springframework.context.annotation.Configuration;

import org.springframework.web.servlet.config.annotation.InterceptorRegistry;

import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration // 告诉Spring Boot这是个配置类

public class InterceptorConfig implements WebMvcConfigurer {

@Override

public void addInterceptors(InterceptorRegistry registry) {

registry.addInterceptor(new LoginCheckInterceptor()) // 注册刚才写的拦截器

.addPathPatterns("/api/**") // 要拦截的路径:所有/api开头的接口

.excludePathPatterns("/api/user/login", "/api/user/register"); // 排除的路径:登录、注册接口不用检查

}

}

`

第三步:测试一下拦截效果

写好之后,启动Spring Boot项目,用工具(比如Postman)测一下:先访问/api/user/login,返回登录成功;再访问/api/order/list(一个需要登录的接口),如果没带登录凭证,就会收到“请先登录”的提示,这说明拦截器生效了;带上凭证再访问,就能正常拿到订单数据,说明拦截器的逻辑没问题。

其实除了登录检查,拦截器还能做很多事,比如统计每个接口的响应时间——可以在preHandle里记录当前时间,在afterCompletion里用结束时间减开始时间,就能算出耗时;也可以过滤请求里的敏感词,在preHandle里检查请求参数有没有敏感词,有的话直接拦截。

用Spring Boot做拦截器的核心就是两步:写拦截逻辑的类,再把它注册到配置类里指定规则,不用每个接口重复写公共代码,既能减少冗余,又方便后期统一修改。

上一篇 TypeScript 如何用 webpack 编译