天行健,君子以自强不息;地势坤,君子以厚德载物。
每个人都有惰性,但不断学习是好好生活的根本,共勉!
文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。
文章目录
- 一、前言
- 二、代码
- 1. 依赖pom.xml
- 2. 主程序类Application.java
- 3. 请求控制类AopController.java
- 4. Aop拦截类AspectExecution.java
- 三、执行
- 1. 执行程序
- 2. 发送请求
- 3. 控制台输出
一、前言
关于AOP的使用可参考: Java AOP 简单实例演示
本篇使用AOP的 @Before注解进行全局请求的拦截,并在所有拦截的请求执行前进行请求参数的校验,校验通过则执行请求,校验不通过则抛错终止所拦截的请求。
具体:
在用户登录时,后端生成一个token字符串,存入redis并定义过期时间,同时给到前端,此时前端的操作每个请求都会带着请求的缓存进行访问调用
服务中的每个请求头中都含有token的参数值,用户每次访问调用一个接口时都会被aop拦截进行token校验
redis中的token与用户请求时的token一致则正常执行,不一致则抛错终止该请求的执行
二、代码
1. 依赖pom.xml
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.7.3</version></dependency><!--集成Redis依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><version>2.7.3</version></dependency><!--json 工具--><dependency><groupId>com.alibaba.fastjson2</groupId><artifactId>fastjson2</artifactId><version>2.0.33</version></dependency><!--项目注解工具--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.24</version></dependency><!--aop--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId><version>2.7.3</version></dependency></dependencies>
2. 主程序类Application.java
import org.aspectj.lang.annotation.Aspect;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;/*** @ClassDescription:* @JdkVersion: 1.8* @Author: 李白* @Created: 2024/3/18 14:12*/
@Aspect
@SpringBootApplication
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}
}
3. 请求控制类AopController.java
import com.alibaba.fastjson2.JSONObject;
import org.springframework.web.bind.annotation.*;/*** @ClassDescription: aop 测试请求类* @JdkVersion: 1.8* @Author: 李白* @Created: 2024/3/18 15:38*/
@RestController
@RequestMapping("/aop")
public class AopController {@PostMapping("/test")public JSONObject test(@RequestHeader("token")String token,@RequestHeader("userGroup")String userGroup,@RequestHeader("username")String username){System.out.println("登录请求触发==========================》》》》》》》》》》》》》》》》");System.out.println("request token: "+token);//定义json对象,存储用户登录信息JSONObject loginInfo = new JSONObject();loginInfo.put("userGroup", userGroup);loginInfo.put("username", username);loginInfo.put("token", token);System.out.println("登录请求结束===================================》》》》》》》》》》》》》》》》》》》》》");return loginInfo;}}
4. Aop拦截类AspectExecution.java
import com.u.u.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;/*** @ClassDescription:* @JdkVersion: 1.8* @Author: 李白* @Created: 2024/3/20 10:34*/
@Aspect
@Component
@Slf4j
@Order(2)
public class TokenAspectExecution {@AutowiredRedisUtil redisUtil;//指定被切入点的方法列表,表示只对aop_test包中以Controller结尾的所有方法生效@Pointcut("execution(public * com..aop_test.*Controller.*(..))")//@Pointcut("execution(public * com..*Controller.*(..))")public void sig(){}@Before("sig()")public void beforeRequest(){log.info("-----------前置通知-----------");ServletRequestAttributes srAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();assert srAttributes != null;HttpServletRequest hsRequest = srAttributes.getRequest();String token = hsRequest.getHeader("token");String username = hsRequest.getHeader("username");System.out.println("token:" + token);System.out.println("username: " + username);//获取到token后去redis中查看//redis中是否含有token的keyboolean hasToken = redisUtil.hasKey("login#" + username);
// boolean hasToken = true;Object object = redisUtil.get("login#" + username);//redis中的token是否与传入的token一致boolean isToken = object.toString().equals(token);
// boolean isToken = false;if (hasToken){//token存在,进行验证,System.out.println("token存在,进行验证");if (isToken){//token校验通过,放行System.out.println("token一致,校验通过,请求放行");}else {//token验证未通过,返回请求失败System.out.println("token不一致,校验失败,请求拒绝");throw new RuntimeException("token不一致,校验失败,请求拒绝");}}else {//验证不通过,请求退回//redis中没有token的键,说明没有登录或登录时间过期(4小时)System.out.println("token不存在,未登录或token过期");throw new RuntimeException("token不存在,未登录或token过期");}}}
三、执行
1. 执行程序
启动主程序运行服务
2. 发送请求
postman发送请求
3. 控制台输出
token不一致,请求中断
感谢阅读,祝君暴富!