springboot幂等切片的实现

网友投稿 535 2022-10-25

springboot幂等切片的实现

springboot幂等切片的实现

目录一、前言二、示例

一、前言

最近测试提某些接口重复提交的问题,想了下应该不http://止是前端点击之后按钮不可点击的问题,后端应该根据登录token、操作方法、参数做多层的判断。

二、示例

切片代码

/**

* 接口幂等切面

* @author Administrator

*/

@Slf4j

@Aspect

@Component

public class ApiIdempotentAspect {

@Resource

RedisUtil redisUtil;

@Resource

UserUtils userUtils;

@Pointcut("@annotation(com.xx.anno.ApiIdempotent)")

private void pointCut() {

}

@Before("pointCut()")

public void doPoint(JoinPoint joinPoint) {

String action = joinPoint.getSignature().getDeclaringTypeName()

.substring(joinPoint.getSignature().getDeclaringTypeName().lastIndexOf(".")+1)

+ "::" + joinPoint.getSignature().getName();

String args = jsON.toJSONString(joinPoint.getArgs());

String token = userUtils.getAuthToke().replace("-","")

.replace("Bearer ","");

String idempotentKey = "api::idempotent::"+token+"::"+action;

//短时间内没进行相似操作

if(redisUtil.hasKey(idempotentKey)){

//接口参数是否一致

String idempotentValue = redisUtil.getCacheObject(idempotentKey);

log.info("idempotentValue : {}",idempotentValue);

if(args.equals(idempotentValue)){

throw new BusinessException("请勿重复操作");

}

} else{

//30s内禁止重复操作

redisUtil.setCacheObject(idempotentKey,args,30, TimeUnit.SECONDS);

}

}

}

用到一个redisutil

@Component

public class RedisUtil {

@Resource

public RedisTemplate redisTemplate;

/**

* 缓存基本的对象,Integer、String、实体类等

*

* @param key 缓存的键值

* @param value 缓存的值

*/

public void setCacheObject(final String key, final T value)

{

redisTemplate.opsForValue().set(key, value);

}

/**

* 缓存基本的对象,Integer、String、实体类等

*

* @param key 缓存的键值

* @param value 缓存的值

* @param timeout 时间

* @param timeUnit 时间颗粒度

*/

public void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit)

{

redisTemplate.opsForValue().set(key, value, timeout, timeUnit);

}

/**

* 设置有效时间

*

* @param key Redis键

* @param timeout 超时时间

* @return true=设置成功;false=设置失败

*/

public boolean expire(final String key, final long timeout)

{

return expire(key, timeout, TimeUnit.SECONDS);

}

/**

* 设置有效时间

*

* @param key Redis键

* @param timeout 超时时间

* @param unit 时间单位

* @return true=设置成功;false=设置失败

*/

public boolean expire(final String key, final long timeout, final TimeUnit unit)

{

return redisTemplate.expire(key, timeout, unit);

}

/**

* 获得缓存的基本对象。

*

* @param key 缓存键值

* @return 缓存键值对应的数据

*/

public T getCacheObject(final String key)

{

ValueOperations operation = redisTemplate.opsForValue();

return operation.get(key);

}

/**

* 删除单个对象

*

* @param key

*/

public boolean deleteObject(final String key)

{

return redisTemplate.delete(key);

}

/**

* 删除集合对象

*

* @param collection 多个对象

* @return

*/

public long deleteObject(final Collection collection)

{

return redisTemplate.delete(collection);

}

/**

* 缓存List数据

*

* @param key 缓存的键值

* @param dataList 待缓存的List数据

* @return 缓存的对象

*/

public long seCUWfctCacheList(final String key, final List dataList)

{

Long count = redisTemplate.opsForList().rightPushAll(key, dataList);

return count == null ? 0 : count;

}

/**

* 获得缓存的list对象

*

* @param key 缓存的键值

* @return 缓存键值对应的数据

*/

public List getCacheList(final String key)

{

return redisTemplate.opsForList().range(key, 0, -1);

}

/**

* 缓存Set

*

* @param key 缓存键值

* @param dataSet 缓存的数据

* @return 缓存数据的对象

*/

public BoundSetOperations setCacheSet(final String key, final Set dataSet)

{

BoundSetOperations setOperation = redisTemplate.boundSetOps(key);

Iterator it = dataSet.iterator();

while (it.hasNext())

{

setOperation.add(it.next());

}

return setOperation;

}

/**

* 获得缓存的set

*

* @param key

* @return

*/

public Set getCacheSet(final String key)

{

return redisTemplate.opsForSet().members(key);

}

/**

* 缓存Map

*

* @param key

* @param dataMap

*/

public void setCacheMap(final String key, final Map dataMap)

{

if (dataMap != null) {

redisTemplate.opsForHaCUWfcsh().putAll(key, dataMap);

}

}

/**

* 获得缓存的Map

*

* @param key

* @return

*/

public Map getCacheMap(final String key)

{

return redisTemplate.opsForHash().entries(key);

}

/**

* 往Hash中存入数据

*

* @param key Redis键

* @param hKey Hash键

* @param value 值

*/

public http:// void setCacheMapValue(final String key, final String hKey, final T value)

{

redisTemplate.opsForHash().put(key, hKey, value);

}

/**

* 获取Hash中的数据

*

* @param key Redis键

* @param hKey Hash键

* @return Hash中的对象

*/

public T getCacheMapValue(final String key, final String hKey)

{

HashOperations opsForHash = redisTemplate.opsForHash();

return opsForHash.get(key, hKey);

}

/**

* 获取多个Hash中的数据

*

* @param key Redis键

* @param hKeys Hash键集合

* @return Hash对象集合

*/

public List getMultiCacheMapValue(final String key, final Collection hKeys)

{

return redisTemplate.opsForHash().multiGet(key, hKeys);

}

/**

* 获得缓存的基本对象列表

*

* @param pattern 字符串前缀

* @return 对象列表

*/

public Collection keys(final String pattern)

{

return redisTemplate.keys(pattern);

}

/**

* 判断key是否还在

* @param key

* @return

*/

public boolean hasKey(final String key){

return redisTemplate.hasKey(key);

}

}

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:新手必学的机器学习常用十大算法
下一篇:交大的秋,是如此美
相关文章

 发表评论

暂时没有评论,来抢沙发吧~