Java防止重复提

具体代码

注解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AvoidRepeatableCommit {

    /**
     * 指定时间内不可重复提交,单位秒
     *
     * @return
     */
    long timeout() default 5;

}

具体业务逻辑

@Aspect
@Component
public class AvoidRepeatableCommitAspect {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private RedisTemplate redisTemplate;

    //controller包的子包里面任何方法
    @Pointcut("execution(public * com.fridge.controller.*.*.*(..))")
    public void checkToken() {
    }

    @Around("checkToken()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        WebResult webResult = new WebResult();
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String ip = getIpAddr(request);

        //获取注解
        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();
        AvoidRepeatableCommit avoidRepeatableCommit = method.getAnnotation(AvoidRepeatableCommit.class);
        if (avoidRepeatableCommit != null) {
            //目标类、方法
            String className = method.getDeclaringClass().getName();
            String name = method.getName();
            String args = Arrays.toString(point.getArgs());
            String ipKey = String.format("%s#%s#%s", className, name, args);
            int hashCode = Math.abs(ipKey.hashCode());
            String key = String.format("%s_%d", ip, hashCode);

            long timeout = avoidRepeatableCommit.timeout();
            if (timeout < 0) {
                //过期时间5分钟
                timeout = 5;
            }
            boolean success = redisTemplate.opsForValue().setIfAbsent(key, UUID.randomUUID().toString(), timeout, TimeUnit.SECONDS);
            if (!success) {
                return webResult.failResult("请勿重复提交");
            }
        }
        //执行方法
        Object object = point.proceed();
        return object;
    }

    /**
     * 获取请求用户的IP地址
     *
     * @param request
     * @return
     */
    public String getIpAddr(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }
}

讲解

主要是利用redis实现防止重复提交

对于同一次请求,进行redis记录,在redis有记录的情况下,进行拦截,没有的情况下请求放行

setIfAbsent 是java中的方法,如果返回false则说明值已经存在则进行拦截,如果返回true则说明没有值,设置值并返回true

# Java  

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×