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

时间: 2024-10-04 01:51:31

spring boot 重复提交的相关文章

Spring boot POST 提交错误 Request header is too large

解决方法 application.yml server: # 单位 KB max-http-header-size: 100000 java.lang.IllegalArgumentException: Request header is too large at org.apache.coyote.http11.Http11InputBuffer.fill(Http11InputBuffer.java:721) ~[tomcat-embed-core-9.0.21.jar:9.0.21] at

spring boot 防止重复提交

服务器端实现方案:同一客户端在2秒内对同一URL的提交视为重复提交 上代码吧 pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocat

spring boot 通过AOP防止API重复请求

实现思路 基于Spring Boot 2.x 自定义注解,用来标记是哪些API是需要监控是否重复请求 通过Spring AOP来切入到Controller层,进行监控 检验重复请求的Key:Token + ServletPath + SHA1RequestParas Token:用户登录时,生成的Token ServletPath:请求的Path SHA1RequestParas:将请求参数使用SHA-1散列算法加密 使用以上三个参数拼接的Key作为去判断是否重复请求 使用Redis存储Key,

Spring MVC拦截器+注解方式实现防止表单重复提交

原理:在新建页面中Session保存token随机码,当保存时验证,通过后删除,当再次点击保存时由于服务器端的Session中已经不存在了,所有无法验证通过. 注,如果是集群的方式,则需要将token放入到缓存中即可. 注解Token代码:java源码  Java代码 复制代码 收藏代码 1[email protected](ElementType.METHOD) 2[email protected] (RetentionPolicy.RUNTIME) 3.public @interface T

spring boot 表单的实体提交错误:Validation failed for object=&#39;book&#39;. Error count: 2

一:错误信息 二:解决方法 在实体后加BindingResult 三:参考链接 http://stackoverflow.com/questions/30297719/cannot-get-validation-working-with-spring-boot-and-thymeleaf spring boot 表单的实体提交错误:Validation failed for object='book'. Error count: 2

Spring MVC防止数据重复提交

现实开发中表单重复提交的例子很多,就包括手上这个门户的项目也有这种应用场景,用的次数多,但是总结,这还是第一次. 一.基本原理 使用token,给所有的url加一个拦截器,在拦截器里面用java的UUID生成一个随机的UUID并把这个UUID放到session里面,然后在浏览器做数据提交的时候将此UUID提交到服务器.服务器在接收到此UUID后,检查一下该UUID是否已经被提交,如果已经被提交,则不让逻辑继续执行下去 二.代码 2.1.注解Token代码: @Target(ElementType

将 Spring boot 项目打成可执行Jar包,及相关注意事项(main-class、缺少 xsd、重复打包依赖)

最近在看 spring boot 的东西,觉得很方便,很好用.对于一个简单的REST服务,都不要自己部署Tomcat了,直接在 IDE 里 run 一个包含 main 函数的主类就可以了. 但是,转念一想,到了真正需要部署应用的时候,不可能通过 IDE 去部署啊.那有没有办法将 spring boot 的项目打包成一个可执行的 jar 包,然后通过 java -jar 命令去启动相应的服务呢? 很明显,是有的.下面,我把我自己的实践过程及遇到的问题,一 一说明一下. 首先,把项目的 POM 配置

Spring MVC服务器端防止重复提交

实现机制是使用token,简单说下: (a)进入下单页,会生成一个token,同时存在两个地方:session(或redis也可以)和页面 (b)提交时,服务器接收到页面的token后,会和session中的token比较,相同则允许提交,同时删除session中的token; (c)如果重复提交,则session中已经没有token(已被步骤b删除),那么校验不通过,则不会真正提交. 拦截器代码:下载 Java代码 package com.chanjet.gov.filter; import 

spring MVC 后台token防重复提交解决方案

看到公司有个部门提出了这个问题,补个粗略的解决方案... 1.编写拦截器 /** * Description: 防止重复提交 * * @Author liam * @Create Date: 2018/3/9 9:22 */ public class AvoidReSubmitIntercepter extends HandlerInterceptorAdapter { private static final String SPLIT_FLAG = "_"; private stat