SpringBoot防止重复请求,重复表单提交超级简单的注解实现

mac2022-06-30  24

1. 注解接口  

/** * @description 防止表单重复提交注解 */@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD)@Documentedpublic @interface DuplicateSubmitToken {

//保存重复提交标记 默认为需要保存 boolean save() default true;}2. 定义异常类

 

/** * 重复提交异常 */public class DuplicateSubmitException extends RuntimeException { public DuplicateSubmitException(String msg) { super(msg); }

public DuplicateSubmitException(String msg, Throwable cause){ super(msg,cause); }} 

3. 拦截器 /** * @description 防止表单重复提交拦截器 */@Aspect@Component@Slf4jpublic class DuplicateSubmitAspect { public static final String DUPLICATE_TOKEN_KEY="duplicate_token_key";

@Pointcut("execution(public * cn.test.core.controller..*(..))")

public void webLog() { }

@Before("webLog() && @annotation(token)") public void before(final JoinPoint joinPoint, DuplicateSubmitToken token){ if (token!=null){ Object[]args=joinPoint.getArgs(); HttpServletRequest request=null; HttpServletResponse response=null; for (int i = 0; i < args.length; i++) { if (args[i] instanceof HttpServletRequest){ request= (HttpServletRequest) args[i]; } if (args[i] instanceof HttpServletResponse){ response= (HttpServletResponse) args[i]; } }

boolean isSaveSession=token.save(); if (isSaveSession){ String key = getDuplicateTokenKey(joinPoint); Object t = request.getSession().getAttribute(key); if (null==t){ String uuid= UUID.randomUUID().toString(); request.getSession().setAttribute(key.toString(),uuid); log.info("token-key="+key); log.info("token-value="+uuid.toString()); }else { throw new DuplicateSubmitException(TextConstants.REQUEST_REPEAT); } }

} }

/** * 获取重复提交key-->duplicate_token_key+','+请求方法名 * @param joinPoint * @return */ public String getDuplicateTokenKey(JoinPoint joinPoint) { String methodName = joinPoint.getSignature().getName(); StringBuilder key=new StringBuilder(DUPLICATE_TOKEN_KEY); key.append(",").append(methodName); return key.toString(); }

@AfterReturning("webLog() && @annotation(token)") public void doAfterReturning(JoinPoint joinPoint,DuplicateSubmitToken token) { // 处理完请求,返回内容 log.info("出来方法:"); if (token!=null){ Object[]args=joinPoint.getArgs(); HttpServletRequest request=null; for (int i = 0; i < args.length; i++) { if (args[i] instanceof HttpServletRequest){ request= (HttpServletRequest) args[i]; } } boolean isSaveSession=token.save(); if (isSaveSession){ String key = getDuplicateTokenKey(joinPoint); Object t = request.getSession().getAttribute(key); if (null!=t){ //方法执行完毕移除请求重复标记 request.getSession(false).removeAttribute(key); log.info("方法执行完毕移除请求重复标记!"); } } } }

/** * 异常 * @param joinPoint * @param e */ @AfterThrowing(pointcut = "webLog()&& @annotation(token)", throwing = "e") public void doAfterThrowing(JoinPoint joinPoint, Throwable e, DuplicateSubmitToken token) { if (null!=token && e instanceof DuplicateSubmitException==false){ //处理处理重复提交本身之外的异常 Object[]args=joinPoint.getArgs(); HttpServletRequest request=null; for (int i = 0; i < args.length; i++) { if (args[i] instanceof HttpServletRequest){ request= (HttpServletRequest) args[i]; } } boolean isSaveSession=token.save(); //获得方法名称 if (isSaveSession){ String key=getDuplicateTokenKey(joinPoint); Object t = request.getSession().getAttribute(key); if (null!=t){ //方法执行完毕移除请求重复标记 request.getSession(false).removeAttribute(key); log.info("异常情况--移除请求重复标记!"); } } } }}4. 控制器    使用方法:在你想要避免重复提交的控制器方法添加注解@DuplicateSubmitToken即可/** * @description */@RestControllerpublic class TestController { @RequestMapping(value = "/test", method = RequestMethod.GET) public Map<String, Object> firstResp (HttpServletRequest request){ Map<String, Object> map = new HashMap<>(); request.getSession().setAttribute("request Url", request.getRequestURL()); map.put("request Url", request.getRequestURL()); return map; }

@DuplicateSubmitToken @RequestMapping(value = "/test/d", method = RequestMethod.GET) public Map<String, Object> test (HttpServletRequest request){

Random r=new Random(); int i = r.nextInt(3); if (i==2){ throw new CustomException("有异常"); }

try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); }

Map<String, Object> map = new HashMap<>(); request.getSession().setAttribute("request Url", request.getRequestURL()); map.put("request Url", request.getRequestURL()); return map; }}5. 测试略过。。。

转载于:https://www.cnblogs.com/bevis-byf/p/11491547.html

相关资源:JAVA上百实例源码以及开源项目
最新回复(0)