拦截器(interceptor)
1. 配置拦截器:
/**
* 登录拦截器
*/
@Component
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//1.获取session
HttpSession session = request.getSession();
//2.获取session中的用户
User user = (User) session.getAttribute("user");
//3.判断用户是否存在
//4.不存在,拦截
if(user == null){
response.setStatus(401);
return false;
}
//5.存在,保存用户到ThreadLocal
UserHolder.saveUser(user);
//6.放行
return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
//释放用户
UserHolder.removeUser();
}
}
----------
2.注册拦截器:
@Configuration
@Slf4j
public class MvcConfig implements WebMvcConfigurer {
//添加拦截器
@Autowired
private LoginInterceptor loginInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
log.info("开始注册拦截器:{}",loginInterceptor);
registry.addInterceptor(loginInterceptor)
//.addPathPatterns("/user/**")
.excludePathPatterns("user/code")
.excludePathPatterns("user/login");
}
}
---------------------------------------------------------
细节:
1.如果不添加 .addPathPatterns()会默认拦截所有请求
2.给registry添加路径时的通配符规则(Ant 风格通配符);
1. ? - 匹配单个字符
作用:匹配任何单个字符(除了路径分隔符 /)
示例:"/user/?"
✅ 匹配:/user/1, /user/a, /user/X
❌ 不匹配:/user/, /user/12, /user/abc, /user/a/b
2. * - 匹配单层路径
作用:匹配零个或多个字符(除了路径分隔符 /),只能匹配一层路径
示例:"/user/*"
✅ 匹配:/user/, /user/profile, /user/123, /user/abc.html
❌ 不匹配:/user/profile/settings, /user/123/orders
3. ** - 匹配多层路径
作用:匹配零个或多个目录和字符,可以跨越多层路径
示例:"/user/**"
✅ 匹配:/user/, /user/profile, /user/profile/settings, /user/123/orders/456
4. {name} - 路径变量(Spring 扩展)
作用:匹配路径片段并将其捕获为变量
示例:"/user/{userId}", "/api/{version}/products"
匹配 /user/123 → userId=123
匹配 /api/v1/products → version=v1
5. {regex} - 正则表达式匹配(Spring 扩展)
作用:使用正则表达式定义更精确的匹配模式
示例:"/user/{id:\\d+}", "/file/{name:[a-z-]+}.{ext}"
{id:\\d+} 只匹配数字
{name:[a-z-]+} 匹配小写字母和连字符
------------------------------------------------------------
2.拦截器的拦截先后顺序,一般先注册的先拦截,也可以设置order值,值越小越先拦截;
例如:
@Configuration
@Slf4j
public class MvcConfig implements WebMvcConfigurer {
//添加拦截器
@Resource
StringRedisTemplate stringRedisTemplate;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor())
.excludePathPatterns("/user/code","/user/login","/blog/hot","/upload/**","/shop-type/**","/voucher/**","/shop/**").order(1); //拦截与登录相关功能的请求
registry.addInterceptor(new RefreshTokenInterceptor(stringRedisTemplate)).order(0); //拦截所有请求
}
}
第二个添加的拦截器反而先执行,因为设置的order值更小;
--------------------------------------------------------------
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Hexo!