spring boot 重复提交

package com.future.interceptor;

import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.baoqilai.scp.web.RestResultGenerator;
import com.future.shiro.ShiroUtils;
import com.google.common.cache.Cache;

@Aspect
@Component
public class NoRepeatSubmitAop {

    private static final Logger logger = LoggerFactory.getLogger(NoRepeatSubmitAop.class);
    
    @Autowired
    private Cache<String, Integer> cache;

    @Around("execution(* com.future.controller.*.*.*(..))&& @annotation(nos)")
    public Object arround(ProceedingJoinPoint pjp, NoRepeatSubmit nos) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        String sessionId = ShiroUtils.getSession().getId().toString();
        HttpServletRequest request = attributes.getRequest();
        String key = sessionId + "-" + request.getServletPath();
        if (cache.getIfPresent(key) != null) {
            logger.error("重复提交");
            return RestResultGenerator.genErrorResult("重复请求,请稍后再试");
        }
        // 如果是第一次请求,就将 key 当前对象压入缓存中
        cache.put(key, 0);
        try {
            return pjp.proceed();
        } catch (Throwable throwable) {
             logger.error("验证重复提交时出现未知异常!");
            return RestResultGenerator.genErrorResult("验证重复提交时出现未知异常!");
        } finally {
            cache.invalidate(key);
        }

    }

}
package com.future.interceptor;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
 *  @功能描述 防止重复提交标记注解
 * @author Administrator
 *
 */
@Target(ElementType.METHOD) // 作用到方法上
@Retention(RetentionPolicy.RUNTIME) // 运行时有效
public @interface NoRepeatSubmit {

}
package com.future.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;

@Configuration
public class UrlCache {

    @Bean
    public Cache<String, Integer> getCache() {
//        return CacheBuilder.newBuilder().expireAfterWrite(2L, TimeUnit.SECONDS).build();// 缓存有效期为2秒
        return CacheBuilder.newBuilder().build();// 不设置缓存有效期
    }
}
@RequestMapping(value = "/test", method = RequestMethod.POST)
    @NoRepeatSubmit
    public RestResult test() {
        int res=6;
        if(res>0){
            return RestResultGenerator.genSuccessResult();
        }
        return RestResultGenerator.genErrorResult("核单失败");
    }
 <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>24.0-jre</version>
        </dependency>

来自:https://www.jianshu.com/p/09c6b05b670a

https://blog.csdn.net/memmsc/article/details/80837996 分布式参考

原文地址:https://www.cnblogs.com/lanliying/p/11652462.html