rk
9 天以前 b4b626357b61d5297b90e3f656be8ef7ad90ddeb
遗漏提交
已添加2个文件
102 ■■■■■ 文件已修改
server/web/src/main/java/com/doumee/api/Repeat/RepeatSubmit.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/web/src/main/java/com/doumee/api/Repeat/RepeatSubmitAspect.java 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/web/src/main/java/com/doumee/api/Repeat/RepeatSubmit.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,28 @@
package com.doumee.api.Repeat;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
// @Target è¡¨ç¤ºè¯¥æ³¨è§£ç”¨äºŽä»€ä¹ˆåœ°æ–¹
// ElementType.CONSTRUCTOR ç”¨åœ¨æž„造器
// ElementType.FIELD ç”¨äºŽæè¿°åŸŸ-属性上
// ElementType.METHOD ç”¨åœ¨æ–¹æ³•上
// ElementType.TYPE ç”¨åœ¨ç±»æˆ–接口上
// ElementType.PACKAGE ç”¨äºŽæè¿°åŒ…
@Target({ElementType.ANNOTATION_TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE})
//@Retention è¡¨ç¤ºåœ¨ä»€ä¹ˆçº§åˆ«ä¿å­˜è¯¥æ³¨è§£ä¿¡æ¯
// RetentionPolicy.SOURCE ä¿ç•™åˆ°æºç ä¸Š
// RetentionPolicy.CLASS ä¿ç•™åˆ°å­—节码上
// RetentionPolicy.RUNTIME ä¿ç•™åˆ°è™šæ‹Ÿæœºè¿è¡Œæ—¶ï¼ˆæœ€å¤šï¼Œå¯é€šè¿‡åå°„获取)
@Retention(RetentionPolicy.RUNTIME)
public @interface RepeatSubmit {
    /**
     * é»˜è®¤çš„间隔时间(ms),小于此时间视为重复提交
     */
    int timeout() default 2000;
}
server/web/src/main/java/com/doumee/api/Repeat/RepeatSubmitAspect.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,74 @@
package com.doumee.api.Repeat;
import com.doumee.core.constants.ResponseStatus;
import com.doumee.core.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;
// å¼€å¯æ—¥å¿—,需要依赖lombok
@Slf4j
// æŠŠä¸€ä¸ªç±»å®šä¹‰ä¸ºåˆ‡é¢ä¾›å®¹å™¨è¯»å–
@Aspect
@Component
public class RepeatSubmitAspect {
    @Resource
    private RedisTemplate<String, String> redisTemplate;
    // è¿™æ˜¯ä¸€ä¸ªçŽ¯ç»•é€šçŸ¥ï¼Œå®ƒä¼šå›´ç»•è¢« @RepeatSubmit æ³¨è§£æ ‡è®°çš„æ–¹æ³•执行,这里的 repeatSubmit ä¸Žä¸‹é¢çš„参数对应
    @Around("@annotation(repeatSubmit)")
    public Object around(ProceedingJoinPoint point, RepeatSubmit repeatSubmit) throws Throwable {
        // èŽ·å–ç”¨æˆ·çš„token验证,这里项目用的是 header é‡Œçš„ Authorization å‚æ•°
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String requestToken = request.getHeader("token");
        // èŽ·å–æ³¨è§£
        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();
        // èŽ·å–ç±»ï¼Œæ–¹æ³•
        String className = method.getDeclaringClass().getName();
        String methodName = method.getName();
        // ç»„装key:用户唯一标识+操作类+方法
        String key = requestToken + "#" + className + "#" + methodName;
        String keyHashCode = String.valueOf(Math.abs(key.hashCode()));
        log.info("key:{},keyHashcode:{}", key, keyHashCode);
        //获取超时时间
        int timeOut = repeatSubmit.timeout();
        log.info("超时时间{}", timeOut);
        // ä»Žç¼“存给中根据key获取数据
        String value = redisTemplate.opsForValue().get(keyHashCode);
        if (value != null) {
            log.info("重复提交");
            // å¦‚æžœvalue不为空; return "请勿重复提交";
            throw new BusinessException(ResponseStatus.MASSIVE_REQUEST);
        } else {
            log.info("首次提交");
            // value为空,则加入缓存,并设置过期过期时间
            redisTemplate.opsForValue().set(keyHashCode, "1", timeOut, TimeUnit.MILLISECONDS);
        }
        //执行Object
        Object object = point.proceed();
        return object;
    }
}