spring boot 使用AOP实现是否已登录检测

这篇具有很好参考价值的文章主要介绍了spring boot 使用AOP实现是否已登录检测。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

        前后端分离的开发中,用户http请求应用服务的接口时, 如果要求检测该用户是否已登录。可以实现的方法有多种, 本示例是通过aop 的方式实现,简单有效。

        约定:前端http的post 请求

export async function request(url,data) {
    const config = {
      method: 'POST',
      headers: {'Content-Type': 'application/json'},
    }
	//每个请求的参数要求附加sessionid, 该sessionid 是登录时生成的
	const paramsData = Object.assign(data,{sessionid:globalData.sessionID || ''})
    config.body = JSON.stringify(paramsData)

    try {
      const res = await window.fetch(url, config)
      if(res.status!==200){
        return {
          status: res.status,
          data:{},
          headers: res.headers,
          url: res.url,
          statusText:res.statusText
        }
      }
    
      return {
        status: res.status,
        data:await res.json(),
        headers: res.headers,
        url: res.url,
      }
    
    } catch (err) {
      return {
        status: 404,
        data:{},
        headers: res.headers,
        url: res.url,
        statusText:'fetch error:'+err.toString()
      }
    }
  }
  

1、在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;
}

   该方法只适用于少部分需要检测,而大部份不需要检测的情况下,如果整个包都需要检测的,利用execution方 法实现文章来源地址https://www.toymoban.com/news/detail-830392.html

 @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;
    }
}

到了这里,关于spring boot 使用AOP实现是否已登录检测的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • JAVA:使用 Spring AOP 实现面向切面编程

    1、简述 在现代的软件开发中,面向切面编程(AOP)是一种重要的编程范式,它允许我们将横切关注点(如日志记录、性能监控、事务管理等)从应用程序的核心业务逻辑中分离出来,以提高代码的模块化和可维护性。Spring 框架提供了强大的 AOP 支持,使得我们可以轻松地实

    2024年04月13日
    浏览(33)
  • spring boot 使用AOP+自定义注解+反射实现操作日志记录修改前数据和修改后对比数据,并保存至日志表

    使用FieldMeta自定义注解,看个人业务自行觉得是否需要重新定义实体 实现类 :通过该实现类获取更新前后的数据。 该实现类的实现原理为:获取入参出入的id值,获取sqlSessionFactory,通过sqlSessionFactory获取selectByPrimaryKey()该方法,执行该方法可获取id对应数据更新操作前后的数

    2024年01月23日
    浏览(41)
  • Spring Boot 中如何使用 Spring Security OAuth2 来实现单点登录

    在现代 Web 应用程序中,单点登录(Single Sign-On,简称 SSO)是一个非常重要的功能。Spring Security OAuth2 是 Spring Security 框架的一个扩展,它提供了一种简单的方式来实现 SSO。在本文中,我们将介绍如何在 Spring Boot 应用程序中使用 Spring Security OAuth2 来实现单点登录。 在开始之前

    2024年02月06日
    浏览(35)
  • 在Spring boot中 使用JWT和过滤器实现登录认证

    在navicat中运行如下sql,准备一张user表 导入pom.xml坐标 在工utils包下创建一个用于生成和解析JWT 令牌的工具类 在pojo包下创建user类 在mapper包下添加 UserMapper接口 在service包下添加 UserService类 在utils包下添加统一响应结果封装类 在controller包下添加LoginController类 这样登录获取toke

    2024年02月06日
    浏览(30)
  • 网页版Java(Spring/Spring Boot/Spring MVC)五子棋项目(二)前后端实现用户的登录和注册功能【用户模块】

    1. 用户id 2. 用户名 3. 密码 4. 天梯积分 5. 总场数 6. 获胜场数 和数据库的数据一一对应 1. 连接数据库(application.yml连接数据库) 这个可以直接赋值代码 2. 创建UserMapper的Java接口(interface UserMapper) 创建接口,在UserMapper.xml实现 在model中创建 需要实现@Mapper注释 3. 创建UserMappe

    2024年02月13日
    浏览(36)
  • 基于Face++,使用Spring Boot+Elemnet-UI实现人脸识别登录。

    上一篇文章只是封装了人脸检测的一些工具类,要实现刷脸登录,我们首先得思考一个问题,就是如何将我们的人脸和登录账户信息进行绑定,让它通过人脸就能识别到当前登录的账户是谁的账户。 这个问题我们可以这样解决,我浏览Face++的官网发现它还有人脸比对的一个

    2024年02月04日
    浏览(30)
  • 使用Spring Boot Security 实现多认证 手机号登录 微信扫码登录 微信扫码注册

    Spring Boot 3.x Spring Security 5.7 Spring Redis MyBatis plus 前端 Vue 公司 最近有个新项目 使用单点登录 sso 百度了一圈 也没怎么找到微信扫码注册的功能于是自己写 需求就是 手机 + 密码登录 微信扫码登录 微信扫码注册 微信二维码 登录 和注册二合一 具体实现 稍后我会说 本教程将指导

    2024年04月10日
    浏览(42)
  • spring-boot-starter-aop及其使用场景说明

    如今,AOP(Aspect Oriented Programming)已经不是什么崭新的概念了,在经历了代码生成、动态代理、字节码增强甚至静态编译等不同时代的洗礼之后,Java 平台上的 AOP 方案基本上已经以 SpringAOP 结合 AspectJ 的方式稳固下来(虽然大家依然可以自己通过各种字节码工具偶尔“打造一

    2024年02月03日
    浏览(69)
  • Spring Boot学习随笔- 实现AOP(JoinPoint、ProceedingJoinPoint、自定义注解类实现切面)

    学习视频:【编程不良人】2021年SpringBoot最新最全教程 问题 现有业务层开发存在问题 额外功能代码存在大量冗余 每个方法都需要书写一遍额外功能代码不利于项目维护 Spring中的AOP AOP:Aspect 切面 + Oriented 面向 Programmaing 面向切面编程 Aspect(切面) = Advice(通知) + Pointcut(

    2024年02月04日
    浏览(33)
  • spring boot整合第三方微信开发工具 weixin-java-miniapp 实现小程序微信登录

    有时候项目需要用到微信登录或获取用户的手机号码,weixin-java-miniapp是一个好用的第三方工具,不用我们自己写httpcline调用。 导入jar包 添加一个resource.properties文件,写上小程序的appid和secret 添加两个配置文件 WxMaProperties.java WxMaConfiguration.java 如何使用 小程序给微信发送消息

    2024年02月16日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包