当前位置:   article > 正文

springboot自定义注解实现防重复提交(服务缓存)_spring boot使用@repeatsubmit 防止重复提交

spring boot使用@repeatsubmit 防止重复提交

缓存基于redis

  1. @Target(ElementType.METHOD,ElementType.TYPE)
  2. @Retention(RetentionPolicy.RUNTIME)
  3. public @interface RepeatSubmit {
  4. /**
  5. * 需要忽略的参数
  6. * @return
  7. */
  8. String[] ignoreParam() default {};
  9. /**
  10. *
  11. * @return
  12. */
  13. String returnObj() default "";
  14. /**
  15. * 单位时间默认3秒
  16. * @return
  17. */
  18. long unitTime() default 3L;
  19. /**
  20. * 是否限制为同一ip
  21. * @return
  22. */
  23. boolean limitIp() default false;
  24. }
  1. @Aspect
  2. @Component
  3. @Slf4j
  4. public class RepeatSubmitAspect {
  5. @Autowired
  6. private RedisClient redisClient;
  7. @Pointcut("@annotation(com.*类全路径*.RepeatSubmit)||@within(com.*类全路径*.RepeatSubmit)")
  8. public void cut() {
  9. }
  10. @Around("cut()")
  11. public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
  12. RepeatSubmit repeatSubmit = getAnnotation(proceedingJoinPoint);
  13. Object o = proceedingJoinPoint.proceed();
  14. if(Objects.isNull(repeatSubmit)){
  15. log.info("【repeatsubmit】缓存失败获取不到缓存目标annotation");
  16. return o;
  17. }
  18. String[] ignoreArr = repeatSubmit.ignoreParam();
  19. List ignoreList = CollectionUtils.arrayToList(ignoreArr);
  20. String returnObj = repeatSubmit.returnObj();
  21. StringBuilder key = new StringBuilder("repeatCheck-");
  22. //类名
  23. String className = proceedingJoinPoint.getSignature().getDeclaringTypeName();
  24. //方法名称
  25. String methodName = proceedingJoinPoint.getSignature().getName();
  26. key.append(className);
  27. key.append(methodName);
  28. ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
  29. if(Objects.isNull(attributes)){
  30. log.info("【repeatsubmit】缓存失败获取不到缓存目标attributes");
  31. return o;
  32. }
  33. HttpServletRequest request = attributes.getRequest();
  34. Map<String, String[]> map = request.getParameterMap();
  35. //方法参数
  36. map.forEach((k,v) -> {
  37. if(!ignoreList.contains(k)){
  38. for (String s : v) {
  39. key.append(s);
  40. }
  41. }
  42. });
  43. if(repeatSubmit.limitIp()){
  44. key.append(request.getRemoteHost());
  45. }
  46. long unitTime = repeatSubmit.unitTime();
  47. //检查是否为重复提交
  48. Object result = redisClient.get(key.toString());
  49. if(Objects.isNull(result)){
  50. if(!StringUtils.hasText(returnObj)){
  51. redisClient.set(key.toString(), BaseResult.success(),unitTime);
  52. }else{
  53. redisClient.set(key.toString(), returnObj,unitTime);
  54. }
  55. redisClient.set(key.toString(), o ,unitTime);
  56. return o;
  57. }else{
  58. log.info("【repeatsubmit】从缓存中获取返回数据:{}",result);
  59. return result;
  60. }
  61. }
  62. /**
  63. * 获得注解
  64. * @param joinPoint
  65. * @return
  66. * @throws Exception
  67. */
  68. private static RepeatSubmit getAnnotation(JoinPoint joinPoint){
  69. Signature signature = joinPoint.getSignature();
  70. MethodSignature methodSignature = (MethodSignature) signature;
  71. Method method = methodSignature.getMethod();
  72. if (method != null) {
  73. return method.getAnnotation(RepeatSubmit.class);
  74. }
  75. return null;
  76. }

说明:单位时间内(unitTime)参数一样的重复请求会直接从redis中读取上次的缓存结果返回

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/550770
推荐阅读
相关标签
  

闽ICP备14008679号