在springboot中用AOP实现重复提交拦截

前言

在日常开发者,我们常常会遇到提交表单因为网络问题或其他原因导致无响应而重复提交的情况,这个时候常用解决办法是前端点击后在一定时间内或者没有返回借结果前将按钮设置为不可点击状态,或者弹出一个加载的模态窗口,成功响应后关闭。

前端添加验证是一种手段,但是可能每个提交都需要添加,或者使用前端框架,这无异于增加了前端的工作量,有时候甚至忘记加。这个时候我们可以在服务器也实现重复提交拦截,做到双保险

实现思路

利用注解配置各个请求重复提交的时间间隔规则,然后再用aop的方式切入。

定义注解

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface DuplicateSubmit {

    /** 间隔多长时间算重复提交*/
    int time() default 1;
    
}

aop实现,使用redis缓存请求路径

@Aspect
@Component
public class DuplicateSubmitAop {
    
    private Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    private CacheService cacheService;

    @Around("execution(* com.reaps.modules.*.web.*Controller.*(..)) && @annotation(ds)")
    public Object arround(ProceedingJoinPoint pjp, DuplicateSubmit ds) {
        try {
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            String sessionId = RequestContextHolder.getRequestAttributes().getSessionId();
            HttpServletRequest request = attributes.getRequest();
            String key = sessionId + "-" + request.getServletPath() + (StringUtils.isEmpty(request.getQueryString()) ? "" : request.getQueryString());
            if (!cacheService.isExist(key)) {// 如果缓存中有这个url视为重复提交
                Object o = pjp.proceed();
                cacheService.set(key, key, ds.time());
                return o;
            } else {
                logger.error("重复提交  sessionId : {} url : {} queryString : {}" , sessionId , request.getServletPath() , request.getQueryString());
                return null;
            }
        } catch (Throwable e) {
            e.printStackTrace();
            logger.error("验证重复提交时出现未知异常!");
            return "{\"code\":1,\"message\":\"验证重复提交时出现未知异常!\"}";
        }

    }

}

你可能感兴趣的:(在springboot中用AOP实现重复提交拦截)