1.注解接口 /** * @description 防止表單重復提交注解 */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) @Documented public @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 @Slf4j public 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 */ @RestController public 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.測試略過。。。