被 Netty 搞昏了头,先学一下幂等性压压惊吧 (1),只需一篇文章吃透 Java 多线程技术
lua 脚本----> checkidem.lua
放在 resources 目录下
//获取 token----> redis: get token
local current = redis.call('GET',KEYS[1])
//如果不存在返回-1
if
current == false then
return '-1'
end
//访问一次之后,删除 token
local isdel = redis.call('DEL',KEYS[1])
//如果删除成功就返回'1'
if isdel == 1 then
return '1'
else
//删除失败,说明 token 不存在
return '0'
end
redis 工具类------> RedisLuaUtil.java
用于运行 lua 脚本
/**
redis 解析 lua 工具类
*/
@Component
public class RedisLuaUtil {
//注入 stringRedisTemplate
@Resource
private StringRedisTemplate stringRedisTemplate;
//运行 lua 脚本
public String runLuaScript(String luaFileName, List<String> keys){
DefaultRedisScript<String> redisScript = new DefaultRedisScript<>();
//读取 lua 脚本文件
redisScript.setScriptSource(
new ResourceScriptSource(
new ClassPathResource(luaFileName)
)
);
//lua 返回值类型
redisScript.setResultType(String.class);
//值参数
String argson = "none";
//执行 lua 脚本,获取返回值,lua 返回的内容主要看
String result = stringRedisTemplate.execute(redisScript, keys, argson);
return result;
}
/**
校验 token
@param request
*/
public String checkToken(HttpServletRequest request) {
//获取 token,从 request 中获取
String token = request.getParameter("token");
//将 token 存储到 list 中
List<String> keys = new ArrayList<>();
keys.add(token);
//调用运行 lua 脚本的方法,并且传入 lua 文件的名称及 token 集合
String result = this.runLuaScript("checkidem.lua", keys);
//根据自定义的 lua 脚本,会返回三种返回值:
//1. GET token 不存在时返回-1
//2. DEL token 成功时,返回 1
//3. DEL token 不成功,返回 0
if(result.equals("1")){
return "保存成功";
}else{
return "请勿重复提交";
}
}
}
生成 token、模拟保存用户操作、测试
//自动注入 redisTemplate,用于存储 token 到 redis 中
@Autowired
private StringRedisTemplate stringRedisTemplate;
//自动注入自定义的 Redis Lua 工具类
@Autowired
private RedisLuaUtil redisLuaUtil;
(1) 生成 token
@GetMapping("/getToken")
public String getToken(){
//生成 UUID,作为 token
String result = UUID.randomUUID().toString();
//将生成的 token 保存到 redis 中
stringRedisTemplate.opsForValue().set(result,result);
//返回给用户
return result;
}
(2) 模拟保存用户操作
@GetMapping("/saveUser")
public String saveUser(HttpServletRequest request){
//执行自定义的 RedisLuaUtil 类,用于校验是否为重复保存
String result = redisLuaUtil.checkToken(request);
//返回给用户
return result;
}
(3) 测试
======
第一:首先调用**/getToken**操作,生成 token
request:
http://localhost:8080/getToken
respones:
91a23e2b-52ab-4867-90bc-737f31bb7ac3
评论