java redis防止重复提交请求_spring boot 防止重复提交

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

上代码吧

pom.xml

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

4.0.0

com.example

springboot-repeat-submit

1.0

jar

org.springframework.boot

spring-boot-starter-parent

2.0.4.RELEASE

UTF-8

UTF-8

1.8

org.springframework.boot

spring-boot-starter-web

org.springframework.boot

spring-boot-starter-aop

com.google.guava

guava

24.0-jre

org.springframework.boot

spring-boot-maven-plugin

logback.xml

%d[%F:%L][%p]:%m%n

Application.javapackage com;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;/**

* @author www.gaozz.club

* @功能描述 防重复提交

* @date 2018-08-26

*/@SpringBootApplicationpublic class Application {    public static void main(String[] args) {

SpringApplication.run(Application.class, args);

}

}

自定义注解NoRepeatSubmit.javapackage com.common;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) // 运行时有效

/**

* @功能描述 防止重复提交标记注解

* @author www.gaozz.club

* @date 2018-08-26

*/

public @interface NoRepeatSubmit {

}

aop解析注解NoRepeatSubmitAop.javapackage com.common;import javax.servlet.http.HttpServletRequest;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;@Aspect@Component/**

* @功能描述 aop解析注解

* @author www.gaozz.club

* @date 2018-08-26

*/public class NoRepeatSubmitAop {    private Log logger = LogFactory.getLog(getClass());    @Autowired

private Cache cache;    @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();            if (cache.getIfPresent(key) == null) {// 如果缓存中有这个url视为重复提交

Object o = pjp.proceed();

cache.put(key, 0);                return o;

} else {

logger.error("重复提交");                return null;

}

} catch (Throwable e) {

e.printStackTrace();

logger.error("验证重复提交时出现未知异常!");            return "{\"code\":-889,\"message\":\"验证重复提交时出现未知异常!\"}";

}

}

}

缓存类package com.common;import java.util.concurrent.TimeUnit;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/**

* @功能描述 内存缓存

* @author www.gaozz.club

* @date 2018-08-26

*/public class UrlCache {    @Bean

public Cache getCache() {        return CacheBuilder.newBuilder().expireAfterWrite(2L, TimeUnit.SECONDS).build();// 缓存有效期为2秒

}

}

测试Controllerpackage com.example;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import com.common.NoRepeatSubmit;/**

* @功能描述 测试Controller

* @author www.gaozz.club

* @date 2018-08-26

*/@RestControllerpublic class TestController {

@RequestMapping("/test")

@NoRepeatSubmit

public String test() {        return ("程序逻辑返回");

}

}

然后F5刷新查看效果

AAffA0nNPuCLAAAAAElFTkSuQmCC

QQ图片20180914165017.png

以下为新版内容:解决了程序集群部署时请求可能会落到多台机器上的问题,把内存缓存换成了redis

application.ymlspring:  redis:    host: 192.168.1.92

port: 6379    password: 123456

RedisConfig.javapackage com.common;import org.springframework.boot.context.properties.ConfigurationProperties;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.data.redis.connection.RedisStandaloneConfiguration;import org.springframework.data.redis.connection.jedis.JedisClientConfiguration;import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;import org.springframework.data.redis.core.RedisTemplate;@Configurationpublic class RedisConfig {    @Bean

@ConfigurationProperties(prefix = "spring.redis")    public JedisConnectionFactory getConnectionFactory() {        return new JedisConnectionFactory(new RedisStandaloneConfiguration(), JedisClientConfiguration.builder().build());

}    @Bean

 RedisTemplate getRedisTemplate() {

RedisTemplate redisTemplate = new RedisTemplate();

redisTemplate.setConnectionFactory(getConnectionFactory());        return redisTemplate;

}

}

作者:不知不怪

链接:https://www.jianshu.com/p/09c6b05b670a

你可能感兴趣的:(java,redis防止重复提交请求)