本文主要说明使用aspect+redis实现重复提交的校验。

注解声明

Resubmit.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Resubmit {
    /**
     *
     * @return default cache key
     */
    String cacheKey() default "default";

    /**
     *
     * @return timeout default unit is seconds
     */
    long timeout() default  10L;
}

切面设计

ResubmitAspect.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
@Aspect
@Component
@Slf4j
public class ResubmitAspect {
    @Autowired
    @Qualifier("redisCacheService")
    private CacheService cacheService;

    @Pointcut("@annotation(Resubmit)")
    public void pointcut() {
    }
    
    private static final String prefix = ":resubmit:";
    
    @Around(value = "pointcut()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        Resubmit resubmit = getResubmitAnn(pjp);
        //TODO 这里需要根据情况替换掉session_id
        String cachekey = resubmit.cacheKey()+":"+"session_id";
        Object obj =null;
        if (!getExcelRedis(cachekey)) {
            obj = pjp.proceed();
            setExcelRedis(cachekey,resubmit.timeout());
        } else {
            throw new ApiException(ApiErrorCode.OPERATOR_TOO_FAST);
        }
        return obj;
    }
    
    private Boolean getExcelRedis(String cacheKey) {
        Optional<Object> excelFlag = cacheService.get(prefix + cacheKey);
        Object excel = excelFlag.orElse(null);
        Boolean returnExcel;
        log.info(String.valueOf(excel));
        if (excel == null) {
            returnExcel = false;
        } else {
            returnExcel = Boolean.valueOf(excel.toString());
        }
        return returnExcel;
    }
    
    private void setExcelRedis(String cacheKey, Long timeOut) {
        cacheService.put(prefix + cacheKey, true, timeOut, TimeUnit.SECONDS);
    }
    
    private Resubmit getResubmitAnn(ProceedingJoinPoint joinPoint)
            throws Exception {
        String targetName = joinPoint.getTarget().getClass().getName();
        String methodName = joinPoint.getSignature().getName();
        Object[] arguments = joinPoint.getArgs();
        Class targetClass = Class.forName(targetName);
        Method[] methods = targetClass.getMethods();
        Resubmit resubmit = null;
        for (Method method : methods) {
            if (method.getName().equals(methodName)) {
                Class[] clazzs = method.getParameterTypes();
                if (clazzs.length == arguments.length) {
                    resubmit = method.getAnnotation(
                            Resubmit.class);
                    break;
                }
            }
        }
        return resubmit;
    }

}