AOP|Springboot + redis 使用AOP实现防止重复提交问题

springboot + redis 使用AOP实现防止重复提交问题 一,定义自定义注解。
我在里面定义了一个锁住接口时间的方法,默认值为10。

package com.nci.common.annotation; 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) public @interface NoRepeatSubmit { /** * 设置请求锁定时间 * * @return */ int lockTime() default 10; }

【AOP|Springboot + redis 使用AOP实现防止重复提交问题】二,添加一个切面
采用Redis来缓存提交接口的唯一标识,然后设置过期时间,唯一标识我才用接口的URL和用户的token组合在一起就能达到唯一,用户每发起第一次添加请求,会经过界面,在切面获取信息后组装起来存入Redis,当用户后续发起请求时,首先判断Redis中是否缓存了这个key,如果缓存了,则证明已经提交,于是反馈给前端,如果不存在,证明没有提交,则存入Redis。
package com.nci.common.aspect; import com.nci.common.annotation.NoRepeatSubmit; import com.nci.common.utils.R; import com.nci.common.utils.RequestUtils; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; import org.springframework.util.Assert; import javax.servlet.http.HttpServletRequest; import java.util.concurrent.TimeUnit; /** *重复提交切面 */ @Aspect @Component public class RepeatSubmitAspect {@Autowired private RedisTemplate redisTemplate; @Pointcut("@annotation(noRepeatSubmit)") public void pointCut(NoRepeatSubmit noRepeatSubmit) { }@Around("pointCut(noRepeatSubmit)") public Object around(ProceedingJoinPoint pjp, NoRepeatSubmit noRepeatSubmit) throws Throwable { int lockSeconds = noRepeatSubmit.lockTime(); HttpServletRequest request = RequestUtils.getRequest(); Assert.notNull(request, "request can not null"); // 此处可以用token或者JSessionId String token = request.getHeader("token"); String path = request.getServletPath(); String sign = path + "/" + token; Boolean key = redisTemplate.hasKey(sign); if(key){ return R.error("重复请求,请稍后再试"); } redisTemplate.opsForValue().set(sign,sign,lockSeconds, TimeUnit.SECONDS); return pjp.proceed(); }}

package com.nci.common.utils; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; public class RequestUtils { public static HttpServletRequest getRequest() { ServletRequestAttributes ra= (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); return ra.getRequest(); } }

三,方法上加上注解
@NoRepeatSubmit @PostMapping("/saveData") public R saveData(@RequestBody XgxxVo vo){ User user = getUser(); Integer res = XgxxService.saveData(vo,user); if(res == 1){ return R.ok(); } return R.error("保存数据失败"); }

    推荐阅读