1. 前言
昨天去面试,被问懵的一个面试题,面试官看了一下简历,轻笑了一声原来你是用拦截器做的token校验啊,那么改用aop你怎么去做校验。我当时脑袋一篇空白。下面就写个小demo
2. aop通知
先回顾一下aop的通知,aop通知有五种分别如下
- 前置通知:方法执行前通知
- 后置通知:方法执行后通知
- 环绕通知:方法执行中通知
- 异常抛出通知:方法抛出异常
- 引介通知:类中增加新的方法属性
我们需要校验用户进行拦截oken,那么在执行到这个方法的时候拦截到,就需要用到环绕通知。
3. 导入Maven依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.21</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
4. 实际代码
AOP拦截类
package com.yefeng.utils;
/**
* @author 叶枫
* @version 1.0.0
* @create 2023/10/25 15:23
*/
import cn.hutool.jwt.JWTUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
/**
* 使用aop进行token校验
* @author yefeng
*/
@Aspect
@Component
@Slf4j
public class TokenVerificationAop {
/**
* 登录路径 ->放行
*/
private static final String LOGIN = "login";
/**
* @Pointcut 声明切入点表达式。
* 注意此处扫描的是你的Controller层接口位置
*/
@Pointcut("execution(public * com.yefeng.controller..*..*(..))")
public void pointcut() {
}
/**
* @Around 环绕通知
* @Around("pointcut()") 可以理解为对这个方法进行环绕通知
* ProceedingJoinPoint 参数 用于环绕通知,
* 使用proceed()方法来执行目标方法,可以理解为 前置通知结束 开始执行使用该注解的方法。
*/
@Around("pointcut()")
public Object doBefore(ProceedingJoinPoint joinPoint) throws Throwable {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
assert attributes != null;
HttpServletRequest request = attributes.getRequest();
String token = request.getHeader("Authorization");
if (request.getRequestURI().contains(LOGIN)) {
return joinPoint.proceed();
}
if (StringUtils.isNotBlank(token)) {
try {
JWTUtil.parseToken(token);
} catch (Exception e) {
// 解析jwt令牌出错, 说明令牌过期或者伪造等不合法情况出现 401
log.info("AuthorizeFilter 解析jwt令牌出错", e);
//此处可以返回自定义 Result结果对象 转成Json格式
throw new Exception("解析jwt令牌出错");
}
} else {
log.info("AuthorizeFilter 登录令牌不存在");
throw new Exception("登录令牌不存在");
}
//执行业务逻辑,放行
return joinPoint.proceed();
}
}
标签:lang,通知,aop,校验,token,import,org
From: https://www.cnblogs.com/lymf/p/17787475.html