一、项目描述
在Java后台开发的小伙伴,都会面临接口被重复请求,生成了脏数据,对数据的统计,查询都会造成错乱。
二、解决方案
通过Java Aop 拦截请求的Url,将请求的url 保存在redis 缓存中,当重复访问时,判断Redis 中是否存在该请求。
三、代码示例
1.创建一个拦截注解
@Inherited
@Target ( ElementType. METHOD)
@Retention ( RetentionPolicy. RUNTIME)
@Documented
public @interface RepeatSubmit {
String name ( ) default "" ;
String delay ( ) default "1L" ;
}
2.对重复的请求进行拦截处理
@Aspect
@Component
@Slf4j
public class RepeatAop {
@Pointcut ( "@annotation(com.linln.component.actionLog.annotation.RepeatSubmit)" )
public void getRepeatSubmit ( ) {
}
@Before ( value = "getRepeatSubmit()" )
public void getSubmit ( JoinPoint joinPoint) {
RequestAttributes ra = RequestContextHolder. getRequestAttributes ( ) ;
ServletRequestAttributes sra = ( ServletRequestAttributes) ra;
assert sra != null;
HttpServletRequest request = sra. getRequest ( ) ;
String url = request. getRequestURL ( ) . toString ( ) ;
String method = request. getMethod ( ) ;
String queryString = request. getQueryString ( ) ;
long startTime = System. currentTimeMillis ( ) ;
log. info ( "{url:{}, method:{}, queryString:{}}" , url, method, queryString) ;
MethodSignature signature = ( MethodSignature) joinPoint. getSignature ( ) ;
Method targetMethod = ( ( MethodSignature) ( joinPoint. getSignature ( ) ) ) . getMethod ( ) ;
com. linln. component. actionLog. annotation. RepeatSubmit anno =
targetMethod. getAnnotation ( com. linln. component. actionLog. annotation. RepeatSubmit. class) ;
String key = url + method + queryString;
String delay = anno. delay ( ) ;
synchronized ( this) {
RedisUtils redisUtils = SpringContextUtil. getBean ( RedisUtils. class) ;
if ( redisUtils. hasKey ( key) ) {
throw new ResultException ( ResultEnum. NO_REPEATING_REQ) ;
}
System. out. println ( signature. getName ( ) ) ;
Map< String, Object> map = new HashMap< > ( ) ;
map. put ( key, "Cache-" + key) ;
redisUtils. hmset ( key, map, Long. parseLong ( delay) ) ;
}
}
3.对有拦截需要的接口添加注解
@PostMapping ( "register" )
@ResponseBody
@RepeatSubmit ( delay = "1" )
public String registerAccount ( @Validated User user, User user) {
userService. save ( user) ;
}