背景
防止用户重复点击在很多地方都有应用,比如防止重复扣款,防止重复启动等等。
环境
SpringBoot+Redis模板
工具类创建redis缓存存储数据类型:
import java.io.Serializable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Component;
@Component
public class PRedisTemplate {
@Autowired
private JedisConnectionFactory jedisConnectionFactory;
private RedisTemplate<String, String> redisTemplateString;
@Bean
public RedisTemplate<String, String> getRedisTemplateString() {
redisTemplateString = new StringRedisTemplate(jedisConnectionFactory);
RedisSerializer<String> keySerializer = new StringRedisSerializer();
redisTemplateString.setKeySerializer(keySerializer);
RedisSerializer<String> valueSerializer = new StringRedisSerializer();
redisTemplateString.setValueSerializer(valueSerializer);
return redisTemplateString;
}
}
思路
在redis中新增一个字符串,当前任务id作为key,常量作为值,设置一定时间内点击次数的判断。
实现
说明:
把前端传来的参数id作为key,存入redis缓存里面。常量1此处仅作为默认值写入value中,仅仅为了实现接口,此处没有任何意义(你也可以写成2,3或其他值)。设置过期时间为10,单位为秒。
也就是说10秒钟之内,这个id再次传过来,redis缓存里面已经有了,ret就会返回false。通过if就可以实现拦截。
String key = String.format("GRADE_TASK_%s", id);
boolean ret = pRedisTemplate.getRedisTemplateString().opsForValue().setIfAbsent(key, "1", 10, TimeUnit.SECONDS);
if (!ret) {
resultData.setMessage("任务已开启");
resultData.setCode(ResultData.STATUS_ERROR);
return resultData;
}