当前位置: 首页 > news >正文

JavaWeb(苍穹外卖)--学习笔记11(Filter(过滤器) 和 Interceptor(拦截器))

前言

本篇文章是学习B站黑马程序员苍穹外卖的学习笔记📑。我的学习路线是Java基础语法-JavaWeb-做项目,管理端的功能学习完之后,又进入用户端的登陆界面的开发,我们可以看到在后续的请求当中,都会在请求头中携带能验证身份的凭证到服务端,而服务端需要统一拦截所有的请求,从而判断是否携带的有合法的JWT令牌,🙌下面主要来说说负责拦截的Filter(过滤器) 和 Interceptor(拦截器)(感觉整个项目用到的地方好多)

其实Filter(过滤器) 和 Interceptor(拦截器)是功能相似,但适用的框架和机制不同的两种工具,但在实际项目中我们使用的都是Interceptor(拦截器),✌️这里先讲Filter然后引出Interceptor

🔍首先来了解一下Filter,他是干啥的,怎么用?

1. Filter是什么?干啥的?

Filter(过滤器) 就像是公司门口的保安和安检门。
你在进公司之前,保安要检查你的身份(比如刷卡),安检门要检查你有没有带违禁品。Filter就是在服务器中检查客户端发来的请求的(比如你发出修改菜品的请求,服务器肯定要验证你是不是员工)。

下面我在黑马程序员讲义里偷了张图(更便于大家理解)

在这里插入图片描述
下面来通过一个例子来看一下Filter过滤器是怎么实现登陆检验的:

在这里插入图片描述
我们来按照上面的流程来写代码:

  1. 创建一个TokenFilter
package com.itheima.filter;/*** 令牌校验过滤器*/
@Slf4j
@WebFilter(urlPatterns = "/*")
public class TokenFilter implements Filter {@Overridepublic void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {HttpServletRequest request = (HttpServletRequest) req;HttpServletResponse response = (HttpServletResponse) resp;//1. 获取请求url。String url = request.getRequestURL().toString();//2. 判断请求url中是否包含login,如果包含,说明是登录操作,放行。if(url.contains("login")){ //登录请求log.info("登录请求 , 直接放行");chain.doFilter(request, response);return;}//3. 获取请求头中的令牌(token)。String jwt = request.getHeader("token");//4. 判断令牌是否存在,如果不存在,返回错误结果(未登录)。if(!StringUtils.hasLength(jwt)){ //jwt为空log.info("获取到jwt令牌为空, 返回错误结果");response.setStatus(HttpStatus.SC_UNAUTHORIZED);return;}//5. 解析token,如果解析失败,返回错误结果(未登录)。try {JwtUtils.parseJWT(jwt);} catch (Exception e) {e.printStackTrace();log.info("解析令牌失败, 返回错误结果");response.setStatus(HttpStatus.SC_UNAUTHORIZED);return;}//6. 放行。log.info("令牌合法, 放行");chain.doFilter(request , response);}}
  1. 在启动类上面加上一个注解@ServletComponentScan
@ServletComponentScan //开启对Servlet组件的支持
@SpringBootApplication
public class TliasManagementApplication {public static void main(String[] args) {SpringApplication.run(TliasManagementApplication.class, args);}
}

✨在用Interceptor2.5.2 令牌校验时也是一样,

  1. 创建 TokenInterceptor 包
@Slf4j
@Component
public class TokenInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//1. 获取请求url。String url = request.getRequestURL().toString();//2. 判断请求url中是否包含login,如果包含,说明是登录操作,放行。if(url.contains("login")){ //登录请求log.info("登录请求 , 直接放行");return true;}//3. 获取请求头中的令牌(token)。String jwt = request.getHeader("token");//4. 判断令牌是否存在,如果不存在,返回错误结果(未登录)。if(!StringUtils.hasLength(jwt)){ //jwt为空log.info("获取到jwt令牌为空, 返回错误结果");response.setStatus(HttpStatus.SC_UNAUTHORIZED);return false;}//5. 解析token,如果解析失败,返回错误结果(未登录)。try {JwtUtils.parseJWT(jwt);} catch (Exception e) {e.printStackTrace();log.info("解析令牌失败, 返回错误结果");response.setStatus(HttpStatus.SC_UNAUTHORIZED);return false;}//6. 放行。log.info("令牌合法, 放行");return true;}}
  1. 配置拦截路径
@Configuration  
public class WebConfig implements WebMvcConfigurer {//拦截器对象@Autowiredprivate DemoInterceptor demoInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {//注册自定义拦截器对象registry.addInterceptor(demoInterceptor).addPathPatterns("/**")//设置拦截器拦截的请求路径( /** 表示拦截所有请求).excludePathPatterns("/login");//设置不拦截的请求路径}
}

🔍在项目中的使用也是大差不差,理解了直接套就好:

package com.sky.interceptor;...
/*** jwt令牌校验的拦截器*/
@Component
@Slf4j
public class JwtTokenAdminInterceptor implements HandlerInterceptor {@Autowiredprivate JwtProperties jwtProperties;/*** 校验jwt** @param request* @param response* @param handler* @return* @throws Exception*/public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("当前线程的ID"+Thread.currentThread().getId());//判断当前拦截到的是Controller的方法还是其他资源if (!(handler instanceof HandlerMethod)) {//当前拦截到的不是动态方法,直接放行return true;}//1、从请求头中获取令牌String token = request.getHeader(jwtProperties.getAdminTokenName());//2、校验令牌try {log.info("jwt校验:{}", token);Claims claims = JwtUtil.parseJWT(jwtProperties.getAdminSecretKey(), token);Long empId = Long.valueOf(claims.get(JwtClaimsConstant.EMP_ID).toString());log.info("当前员工id:", empId);BaseContext.setCurrentId(empId);//3、通过,放行return true;} catch (Exception ex) {//4、不通过,响应401状态码response.setStatus(401);return false;}}
}
package com.sky.interceptor;import com.sky.constant.JwtClaimsConstant;
import com.sky.context.BaseContext;
import com.sky.properties.JwtProperties;
import com.sky.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;/*** jwt令牌校验的拦截器*/
@Component
@Slf4j
public class JwtTokenUserInterceptor implements HandlerInterceptor {@Autowiredprivate JwtProperties jwtProperties;/*** 校验jwt** @param request* @param response* @param handler* @return* @throws Exception*/public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("当前线程的ID"+Thread.currentThread().getId());//判断当前拦截到的是Controller的方法还是其他资源if (!(handler instanceof HandlerMethod)) {//当前拦截到的不是动态方法,直接放行return true;}//1、从请求头中获取令牌String token = request.getHeader(jwtProperties.getUserTokenName());//2、校验令牌try {log.info("jwt校验:{}", token);Claims claims = JwtUtil.parseJWT(jwtProperties.getUserSecretKey(), token);Long userId = Long.valueOf(claims.get(JwtClaimsConstant.USER_ID).toString());log.info("当前用户id:", userId);BaseContext.setCurrentId(userId);//3、通过,放行return true;} catch (Exception ex) {//4、不通过,响应401状态码response.setStatus(401);return false;}}
}
    /*** 注册自定义拦截器** @param registry*/protected void addInterceptors(InterceptorRegistry registry) {log.info("开始注册自定义拦截器...");registry.addInterceptor(jwtTokenAdminInterceptor).addPathPatterns("/admin/**").excludePathPatterns("/admin/employee/login");registry.addInterceptor(jwtTokenUserInterceptor).addPathPatterns("/user/**").excludePathPatterns("/user/user/login").excludePathPatterns("/user/shop/status");}
http://www.dtcms.com/a/300144.html

相关文章:

  • Windows开发,制作开发软件安装程序(一)
  • MySQL的底层原理--InnoDB数据页结构
  • 关于GateWay网关
  • 基于HMM的词性标注方法详解(HMM+Viterbi,例题分析)
  • 【专业扫盲】电压/电流反馈和串联/并联反馈
  • CSP2025模拟赛2(2025.7.26)
  • 机器人仿真(2)Ubuntu24.04下RTX5090配置IsaacSim与IsaacLab
  • Jenkins持续集成工具
  • swagger基本注解@Tag、@Operation、@Parameters、@Parameter、@ApiResponse、@Schema
  • (1-7-4) MySql 的高级查询
  • 20250726-2-Kubernetes 网络-Service 定义与创建_笔记
  • 【Spring Cloud】微服务学习
  • 超时进行报警例子
  • 在 Windows 系统中实现 WinToGo 的 VHDX 文件切换使用的常见方法
  • 什么是缓存雪崩?缓存击穿?缓存穿透?分别如何解决?什么是缓存预热?
  • Spring AI Alibaba Video 示例
  • 大型微服务项目:听书——12 数据一致性自定义starter封装缓存操作
  • Java设计模式之行为型模式(中介者模式)实现方式与测试方法
  • 大数据之路:阿里巴巴大数据实践——实时技术与数据服务
  • Reeden:跨平台 AI 电子书阅读器
  • leetcode112, 257:二叉树的路径总和、二叉树的所有路径双题对比
  • 【基础完全搜索】USACO Bronze 2020 December - 雏菊链Daisy Chains
  • AI Agent:自主决策的智能助手
  • Javaweb————HTTP消息体拆分讲解
  • ISIS分片扩展实验案例
  • 精密全波整流电路(四)
  • 2025年02月11日 Go生态洞察:Go 1.24 发布亮点全面剖析
  • 【DNS服务配置—实现正反向解析】
  • 宏观杠杆率及其数据获取(使用AKShare)
  • 【C++基础】指针常量 | 常量指针 | int* p | const int* p | int* const p| const int* const p