背景及用途
前端页面出现卡顿,用户反复点击操作按钮,导致后台接口短时间内多次提交
实现步骤
设置切面,增加注解,导致在规定时间内该接口不可重复调用
设置一个接口 NoRepeatSubmit
import java.lang.annotation.*;
@Target(ElementType.METHOD) //注解放置的目标位置,METHOD是可注解在方法级别上
@Retention(RetentionPolicy.RUNTIME) //注解在哪个阶段执行
@Documented //生成文档
public @interface NoRepeatSubmit {
String name() default "name:";
}
实现类
import java.lang.annotation.*;
@Target(ElementType.METHOD) //注解放置的目标位置,METHOD是可注解在方法级别上
@Retention(RetentionPolicy.RUNTIME) //注解在哪个阶段执行
@Documented //生成文档
public @interface NoRepeatSubmit {
String name() default "name:";
}
使用
@GetMapping(value = "/test")
@NoRepeatSubmit
public void test() {
System.out.println("test");
}
补充:下面看下java防止前端重复提交
JAVA利用自定义本地锁解决重复提交的问题
1.引入jar包
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.1-jre</version>
</dependency>
2.自定义本地锁
package com.hzt.listener;
import java.lang.annotation.*;
@Target(ElementType.METHOD) //作用于方法
@Retention(RetentionPolicy.RUNTIME) //运行时有效
@Documented
@Inherited
public @interface LocalLock {
String key() default "";
}
3.自定义注解切面 (aop拦截器实现)
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.TimeUnit;
@Aspect
@Configuration
public class LockMethodInterceptor {
private final Logger log = LoggerFactory.getLogger(LockMethodInterceptor.class);
private static final Cache<String, Object> CACHES = CacheBuilder.newBuilder()
//最大缓存数
.maximumSize(1000)
//设置过期时间
.expireAfterWrite(3, TimeUnit.SECONDS)
.build();
@Around(value = "@annotation(localLock)")
public Object interceptor (ProceedingJoinPoint point, LocalLock localLock) {
//localLock.key() 这个是获取controller的key属性, point.getArgs()获取key的值
String key = getKey(localLock.key(), point.getArgs());
if (StringUtils.isNotBlank(key)) {
if (CACHES.getIfPresent(key) != null) {
throw new RuntimeException("请勿重复提交");
}
//如果是第一次请求, 将key放入缓存
CACHES.put(key, key);
}
try {
return point.proceed();
} catch (Throwable throwable) {
throw new RuntimeException("服务器异常");
} finally {
//标记为无效
// CACHES.invalidate(key);
}
}
private String getKey(String key, Object[] args) {
for (int i = 0; i < args.length; i++) {
key = key.replace("arg[" + i + "]", args[i].toString());
}
return key;
}
4.定义controller接口
@GetMapping("/query")
@LocalLock(key = "param:arg[0]")
public String query (@RequestParam("abc") String abc) {
return "ok";
}
第一次调用结果:
第二次调用结果:
到此这篇关于Java 限制前端重复请求的文章就介绍到这了,更多相关Java 限制重复请求内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!