spring boot中如何使用AOP检测是否登录呢?

重生 SpringBoot 发布时间:2024-02-26 22:45:09 阅读数:15267 1
下文笔者讲述SpringBoot中借助AOP检测是否登录的方法及示例分享,如下所示
实现思路:
   1.引入相应的依赖
   2.编写AOP代码(切面类)
pom.xml引用

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

2、创建插入标记

@Target({ElementType.METHOD}) // 只在对象方法上标记
@Retention(RetentionPolicy.Runtime) //运行时反射
public @interface Interceptor {
    String additionalMessage() default "";
}
 
3、实现切入类

 
@Aspect
@Component
@Slf4j
public class LoggingAspect {
 
    @Autowired
    public StringredisTemplate redisTemplatelocate;
 
    private  <T> T getSessionID(Object postData,Class<T> clazz){
        return (T)postData;
    }
 
    @Around("@annotation(Interceptor)") //有标记的地方将实现以下和切入
    public Object logExecutionTime(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        //获取切入方法的参数,就是前部请求的json数据
        Object[] args = proceedingJoinPoint.getArgs();
 
        //获取其中的sessionid
        // requestBase 实体类只有一个参sessionid , 做为其它实体类的父类,用于接收接口上传的参数。
        RequestBase requestBase=getSessionID(args[0],RequestBase.class);
        log.info("sessionid:{}",requestBase.getSessionid());
 
        //检测该sessionid 是否存在(redis)
        if (requestBase.getSessionid()==null || !redisTemplatelocate.hasKey(requestBase.getSessionid())) {
            //用户未登陆
            throw new Exception("用户未登陆");
        }
 
        //获取  request 和 response
        ServletRequestAttributes servletRequestAttributes = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes());
        log.info("request:{}",servletRequestAttributes.getRequest());
        log.info("response:{}",servletRequestAttributes.getResponse());
 
        MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature();
        String className = methodSignature.getDeclaringType().getSimpleName();
        String methodName = methodSignature.getMethod().getName();
        Instant startTime = Instant.now();
         //实行被切入的方法
        Object result = proceedingJoinPoint.proceed();
        
        String additionalMessage = methodSignature.getMethod().getAnnotation(Interceptor.class).additionalMessage();
        long elapsedTime = Duration.between(startTime, Instant.now()).toMillis();
        log.info("Class Name: {}, Method Name: {}, Additional Message: {}, Elapsed Time: {}ms",
                className, methodName, additionalMessage, elapsedTime);
        log.info("Result: {}", result);
        return result;
    }
}


4.建立api接口,在需要检测的方法上加入@Interceptor 就完成切入的检测。

@RestController
@Slf4j
public class ExampleController {
 
    @PostMapping("/t1")
    @Interceptor(additionalMessage = "要求检测登录")
    @ResponseBody
    public ResponseEntity<RequestBase> getData(@RequestBody DataRequest req) {
        try {
            return new ResponseEntity<>(req, HttpStatus.OK);
        } catch (Exception e) {
            return new ResponseEntity<>(null, HttpStatus.BAD_REQUEST);
        }
    }
}

5.实体类

@Data
public class DataRequest extends RequestBase {
    private  String name;
}
 
 
@Data
public class RequestBase{
    private String sessionid;
}

//@Pointcut("execution(public * com.example.myapp..*.*(..))")
 
@Aspect
@Component
@Slf4j
public class LoginExecution {
 
    @Autowired
    public StringRedisTemplate redisTemplatelocate;
 
    private  <T> T getSessionID(Object postData,Class<T> clazz){
        return (T)postData;
    }
 
    //切入点: com.aop.ttt 下的所有public 方法
    @Pointcut("execution(public * com.aop.ttt..*.*(..))")
    public void publicMethods() {}
 
    @Around("publicMethods()")
    public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
        //获取切入方法的参数,就是前部请求的json数据
        Object[] args = joinPoint.getArgs();
 
        //获取其中的sessionid
        // requestBase 实体类只有一个参sessionid , 做为其它实体类的父类,用于接收接口上传的参数。
        RequestBase requestBase=getSessionID(args[0],RequestBase.class);
        log.info("sessionid:{}",requestBase.getSessionid());
 
        //检测该sessionid 是否存在(redis)
        if (requestBase.getSessionid()==null || !redisTemplatelocate.hasKey(requestBase.getSessionid())) {
            //用户未登陆
            throw new Exception("用户未登陆");
        }
 
        //获取  request 和 response
        ServletRequestAttributes servletRequestAttributes = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes());
        log.info("request:{}",servletRequestAttributes.getRequest());
        log.info("response:{}",servletRequestAttributes.getResponse());
 
 
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        String className = methodSignature.getDeclaringType().getSimpleName();
        String methodName = methodSignature.getMethod().getName();
        Instant startTime = Instant.now();
        //实行被切入的方法
        Object result = joinPoint.proceed();
 
 
        long elapsedTime = Duration.between(startTime, Instant.now()).toMillis();
        log.info("Class Name: {}, Method Name: {}, Elapsed Time: {}ms",
                className, methodName, elapsedTime);
        log.info("Result: {}", result);
        return result;
    }
}
版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。

本文链接: https://www.Java265.com/JavaFramework/SpringBoot/202402/8050.html

最近发表

热门文章

好文推荐

Java265.com

https://www.java265.com

站长统计|粤ICP备14097017号-3

Powered By Java265.com信息维护小组

使用手机扫描二维码

关注我们看更多资讯

java爱好者