web 防重复提交实现

通过注解方式,在aop中判断是否重复提交。
整个流程如下。


image.png

注解

/**
 * @author river
 * @date 2019/5/27 11:38
 **/
@Retention(RUNTIME)
@Target(ElementType.METHOD)
public @interface NoRepeatSubmit {
}

AOP 内处理业务

/**
 * @author river
 * @date 2019/5/27 11:40
 **/
@Aspect
@Component
@Slf4j
public class NoRepeatSubmitAop {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    public static final String NO_REPEAT_COMMIT = "NO_REPEAT_COMMIT:";

    @Around("@annotation(noRepeatSubmit)")
    public Object arround(ProceedingJoinPoint pjp, NoRepeatSubmit noRepeatSubmit) throws Throwable {
        ValueOperations opsForValue = stringRedisTemplate.opsForValue();
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        String sessionId = RequestContextHolder.getRequestAttributes().getSessionId();
        HttpServletRequest request = attributes.getRequest();

        String key = NO_REPEAT_COMMIT + sessionId + "-" + request.getServletPath();
        // 如果缓存中有这个url视为重复提交
        if (opsForValue.get(key) == null) {
            Object o = pjp.proceed();
            opsForValue.set(key, "no repeat commit", 2, TimeUnit.SECONDS);
            return o;
        }

        log.debug("key = {} 重复提交", key);
       // 抛出异常 - 给前端
        throw new Exception("重复提交");
    }
}

这样如果是2秒内 同一个 url 的请求,就会被拦截(抛出异常)。

你可能感兴趣的:(web 防重复提交实现)