> Java > java지도 시간 > 본문

Java는 프런트 엔드에서 반복되는 요청을 어떻게 제한합니까?

WBOY
풀어 주다: 2023-05-14 22:58:04
앞으로
1401명이 탐색했습니다.

배경 및 목적

프런트엔드 페이지가 정지되고 사용자가 작업 버튼을 반복적으로 클릭하여 짧은 시간 내에 백엔드 인터페이스가 여러 번 제출됩니다.

구현 단계

측면 설정 및 주석 추가, 그 결과 지정된 시간 내에 인터페이스가 반복적으로 호출되지 않습니다

인터페이스 설정NoRepeatSubmit

import java.lang.annotation.*;
/**
 * xzj_2022_8_2
 * 重复请求限制切面
 */
@Target(ElementType.METHOD) //注解放置的目标位置,METHOD是可注解在方法级别上
@Retention(RetentionPolicy.RUNTIME) //注解在哪个阶段执行
@Documented //生成文档
public @interface NoRepeatSubmit {
    String name() default "name:";
}
로그인 후 복사
로그인 후 복사

클래스 구현

import java.lang.annotation.*;
/**
 * xzj_2022_8_2
 * 重复请求限制切面
 */
@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. 로컬 잠금 맞춤 설정(AOP 인터셉터 구현)

package com.hzt.listener;
import java.lang.annotation.*;
/**
 * 自定义-控制重复提交锁
 */
@Target(ElementType.METHOD)     //作用于方法
@Retention(RetentionPolicy.RUNTIME)     //运行时有效
@Documented
@Inherited
public @interface LocalLock {

    String key() default "";
}
로그인 후 복사

4. 인터페이스

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;

/**
 * @Desc: 自定义注解拦截器
 * @Author: zmk
 * @Date: 2022/4/2
 */
@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);
        }

    }
    
    /**
     *
     * key 生成策略
     * @param key   key表达式
     * @param args  参数
     * @return  生成的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;
    }
로그인 후 복사

첫 번째 호출 결과:

Java는 프런트 엔드에서 반복되는 요청을 어떻게 제한합니까?두 번째 호출 결과:

위 내용은 Java는 프런트 엔드에서 반복되는 요청을 어떻게 제한합니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:yisu.com
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿