spring boot 防止重复提交

spring boot 防止重复提交

 

服务器端实现方案:同一客户端在2秒内对同一URL的提交视为重复提交

  1. 加入maven内容
  2. 注解接口
  3. 切面拦截
  4. 改时间也可以在切面拦截里面改,使用的时候,在对应的Controller方法中加入注解就可以了@NoRepeatSubmit

 

pom.xml中,增加Maven

<!--数据重复提交解决用下面两个-->
<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>27.1-jre</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

 

 

自定义注解NoRepeatSubmit.java

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD) // 作用到方法上
@Retention(RetentionPolicy.RUNTIME) // 运行时有效
/**
 *@功能描述防止重复提交标记注解
 *@authorcharles
 *@date2020-02-26
 */
public @interface NoRepeatSubmit {
}

 

 

NoRepeatSubmitAop切面拦截,其中多少秒的设置也在这里

import javax.servlet.http.HttpServletRequest;

import com.google.common.cache.CacheBuilder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
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.google.common.cache.Cache;

import java.util.concurrent.TimeUnit;

@Aspect
@Component
/**
 *@功能描述aop解析注解
 *@authorcharles
 *@date2020-02-26
 */
public class NoRepeatSubmitAop {
    private Log logger = LogFactory.getLog(getClass());

    // 最大缓存 100 个,缓存过期时间为2秒
    private final Cache<String, Object> cache = CacheBuilder.newBuilder()
            .maximumSize(100)
            .expireAfterWrite(2, TimeUnit.SECONDS)
            .build();

    @Around("execution(* com.example..*Controller.*(..)) && @annotation(nrs)")
    public Object arround(ProceedingJoinPoint pjp, NoRepeatSubmit nrs) {
        try {
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            String sessionId = RequestContextHolder.getRequestAttributes().getSessionId();
            HttpServletRequest request = attributes.getRequest();
            String key = sessionId + "-" + request.getServletPath();
            // 如果缓存中有这个url视为重复提交
            if (cache.getIfPresent(key) == null) {
                Object o = pjp.proceed();
                cache.put(key, 0);
                return o;
            } else {
                logger.error("重复提交");
//                if(true) {
//                    throw new Exception("模拟未知异常!");
//                }
                return "重复提交了";// 这里,可以改成自己程序中统一的返回格式内容
            }
        } catch (Throwable e) {
            e.printStackTrace();
            logger.error("重复提交时出现其他的未知异常!");
            // 这里,可以改成自己程序中统一的返回格式内容
            return "{\"code\":-1,\"message\":\"重复提交时出现其他的未知异常!\"}";
        }

    }

}

 

 

测试使用

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {
    @RequestMapping("/test")
    @NoRepeatSubmit
    public String test() {
        System.out.println(123);
        return ("测试返回");
    }
}

 

 


版权声明:本文为dingyujiaoyu原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。