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

Springboot+Aop用注解实现阿里云短信验证码校验,校验通过自动删除验证码缓存

1.新建操作类型枚举(这里的IEnum是我自定义的http请求拦截接口,不需要的话可以不用实现)

@Getter
@AllArgsConstructor
public enum OperationType implements IEnum<Integer> {/*** 注册*/SIGN_UP(0),/*** 密码登录*/LOGIN_BY_PWD(1),/*** 验证码登录*/LOGIN_BY_SMS(2),/*** 忘记密码*/FORGET_PWD(3),/*** 修改密码*/MODIFY_PWD(4);@JsonValueprivate final int code;@Overridepublic Integer getCode(){return code;}
}

2.新建校验注解

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SmsValidate {/*** 操作类型* @return*/OperationType operationType() default OperationType.LOGIN_BY_PWD;
}

3.创建验证码校验接口

public interface ISmsValidate {/*** 短信验证码手机号* @return*/String mobile();/*** 短信验证码内容* @return*/String smsCode();
}

4.controller方法请求参数,实现ISmsValidate接口

@Data
public class LoginBySmsDto implements ISmsValidate {@NotBlank(message = "用户名/手机号不能为空")@IsMobileprivate String username;@NotBlank(message = "短信验证码不能为空")private String code;@Overridepublic String mobile() {return this.getUsername();}@Overridepublic String smsCode() {return this.getCode();}
}

5.添加aop切面类

@Aspect
@Component
public class SmsValidateAop {@Autowiredprivate RedisTemplate<String,Object> redisTemplate;@Pointcut(value = "@annotation(com.tfyt.common.annotation.SmsValidate)")public void pointCut(){}@Before(value = "pointCut()")public void before(JoinPoint joinPoint){SmsObj smsObj = getSmsObj(joinPoint);Object cacheCode = redisTemplate.opsForValue().get(RedisKeyConstant.CACHE_SMS_CODE + smsObj.getOperationType() + ":" + smsObj.getMobile());BusinessAssert.notTrue(Objects.equals(cacheCode,smsObj.getCode()),"手机验证码不正确");}@AfterReturning(value = "pointCut()")public void after(JoinPoint joinPoint){SmsObj smsObj = getSmsObj(joinPoint);redisTemplate.delete(RedisKeyConstant.CACHE_SMS_CODE + smsObj.getOperationType() + ":" + smsObj.getMobile());}@Data@AllArgsConstructor@NoArgsConstructorprivate static class SmsObj{private String mobile;private String code;private Integer operationType;}private SmsObj getSmsObj(JoinPoint joinPoint){MethodSignature signature = (MethodSignature) joinPoint.getSignature();SmsValidate annotation = signature.getMethod().getAnnotation(SmsValidate.class);BusinessAssert.isNull(annotation,"系统异常:未查询到注解");BusinessAssert.isNull(annotation.operationType(),"系统异常:未配置操作类型");Object[] args = joinPoint.getArgs();ISmsValidate arg = null;if(args[0] instanceof ISmsValidate){arg = (ISmsValidate) args[0];}BusinessAssert.isNull(arg,"请输入用户名和手机验证码");return new SmsObj(arg.mobile(), arg.smsCode(), annotation.operationType().getCode());}
}

6.往controller的方法上注解

@SmsValidate(operationType = OperationType.LOGIN_BY_SMS)

重启springboot项目,调用接口即可生效,校验通过后会自动删除redis缓存

补一个自定义断言类

public class BusinessAssert {public static void notTrue(boolean condition, String msg){isTrue(!condition, msg);}public static void isTrue(boolean condition, String msg){if(condition){throw new BusinessException(HttpStatus.BAD_REQUEST.value(),msg);}}public static void nonNull(Object object,String msg){if(null!=object){throw new BusinessException(HttpStatus.BAD_REQUEST.value(),msg);}}public static void isNull(Object object,String msg){if(null==object){throw new BusinessException(HttpStatus.BAD_REQUEST.value(),msg);}}public static void isCollectionEmpty(Collection<?> collection,String msg){if(collection == null || collection.isEmpty()){throw new BusinessException(HttpStatus.BAD_REQUEST.value(),msg);}}public static void isCollectionNotEmpty(Collection<?> collection,String msg){if(collection != null && !collection.isEmpty()){throw new BusinessException(HttpStatus.BAD_REQUEST.value(),msg);}}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • TF和TF-IDF区别和联系
  • qt 点击高亮的矩形,且可拖拽 开发过程笔记
  • WEB前端06-BOM对象
  • 【博士每天一篇文献-算法】连续学习算法之HNet:Continual learning with hypernetworks
  • 【ensp】防火墙------NET相关配置实验
  • leetcode_189. 轮转数组
  • LLMs之RAG:GraphRAG(本质是名词Knowledge Graph/Microsoft微软发布)的简介、安装和使用方法、案例应用之详细攻略
  • PAT甲级真题1020树的遍历
  • Spring Boot中@Async注解的使用及原理 + 常见问题及解决方案
  • MFC CRectTracker 类用法详解
  • Linux环境下安装Nodejs
  • Flutter热更新技术探索
  • 【ffmpeg命令入门】重新编码媒体流、设置码率、设置帧速率
  • 昇思25天学习打卡营第21天|DCGAN生成漫画头像
  • 算法学习笔记:贪心算法
  • 【108天】Java——《Head First Java》笔记(第1-4章)
  • 【RocksDB】TransactionDB源码分析
  • 2017前端实习生面试总结
  • Brief introduction of how to 'Call, Apply and Bind'
  • JavaScript中的对象个人分享
  • js学习笔记
  • Laravel 中的一个后期静态绑定
  • TCP拥塞控制
  • Twitter赢在开放,三年创造奇迹
  • ubuntu 下nginx安装 并支持https协议
  • Vue.js源码(2):初探List Rendering
  • Vue2 SSR 的优化之旅
  • vue学习系列(二)vue-cli
  • 阿里云Kubernetes容器服务上体验Knative
  • 工作踩坑系列——https访问遇到“已阻止载入混合活动内容”
  • 看域名解析域名安全对SEO的影响
  • 前端临床手札——文件上传
  • 如何合理的规划jvm性能调优
  • 小程序 setData 学问多
  • 用简单代码看卷积组块发展
  • # 再次尝试 连接失败_无线WiFi无法连接到网络怎么办【解决方法】
  • #预处理和函数的对比以及条件编译
  • $.ajax,axios,fetch三种ajax请求的区别
  • $refs 、$nextTic、动态组件、name的使用
  • (3)llvm ir转换过程
  • (el-Transfer)操作(不使用 ts):Element-plus 中 Select 组件动态设置 options 值需求的解决过程
  • (附源码)php投票系统 毕业设计 121500
  • (附源码)spring boot火车票售卖系统 毕业设计 211004
  • (十一)c52学习之旅-动态数码管
  • (转) ns2/nam与nam实现相关的文件
  • (转)母版页和相对路径
  • (转)总结使用Unity 3D优化游戏运行性能的经验
  • .Net Core中Quartz的使用方法
  • .NET 设计模式—适配器模式(Adapter Pattern)
  • .NET/ASP.NETMVC 深入剖析 Model元数据、HtmlHelper、自定义模板、模板的装饰者模式(二)...
  • .NetCore+vue3上传图片 Multipart body length limit 16384 exceeded.
  • .net访问oracle数据库性能问题
  • //TODO 注释的作用
  • ::
  • :class的用法及应用