问题:用户端有时候提交信息时会短时间内重复点击好几次,此时前端可以做相应处理进行拦截。但是后端也得做相应的处理,需要过滤同一用户短时间内对同一接口的多次请求。
背景:springboot的java项目+分布式服务器架构
方案概述:首先采用redis作为缓存来应对分布式服务器的不同请求。其次采用spring自带的切面功能在需要拦截重复请求的方法上进行注解。
代码:
这里是具体的防止重复提交的代码,通过 @Around("@annotation(com.dazhi.common.aop.NoRepeatSubmitAop)")一行绑定注解类。
不懂切点原理的见aop切点语法
@Aspect
@Component
public class NoRepeatSubmitAop {
private static final Loggerlogger = LoggerFactory.getLogger(ControllerAspect.class);
@Autowired
private StringRedisTemplatestringRedisTemplate;
@Around("@annotation(com.dazhi_park.common.aop.NoRepeatSubmitAop)")
public Objectarround(ProceedingJoinPoint pjp) {
RespJsonObject object =new RespJsonObject();
logger.info("拦截请求!!!!!!!!!!!!");
try {
RequestAttributes ra = RequestContextHolder.getRequestAttributes();
ServletRequestAttributes sra = (ServletRequestAttributes) ra;
HttpServletRequest request = sra.getRequest();
String uri = request.getRequestURI();
String rdsession = request.getParameter("rdsession");
String key = rdsession +"-" + uri;
if (stringRedisTemplate.opsForValue().get(key) ==null) {// 如果缓存中有这个url视为重复提交
Object o = pjp.proceed();
stringRedisTemplate.opsForValue().set(key, "0", 5, TimeUnit.SECONDS);
return o;
}else {
logger.info("重复提交");
object.setRespCode("40000");
object.setRespMessage("重复提交");
return object;
}
}catch (Throwable e) {
logger.info("提交次数过多");
object.setSuccess();
return object;
}
}
}
这是注解类
@Target(ElementType.METHOD) // 作用到方法上
@Retention(RetentionPolicy.RUNTIME) // 运行时有效
/**
* @功能描述 防止重复提交标记注解
* @author www.gaozz.club
* @date 2018-08-26
*/
public @interface NoRepeatSubmitAop {
}
之后在需要的方法上加上注解就好。
网友评论