aop 幂等验证(三)

无法找到公用架包中,aop注解

先看一下模块:

一,公用架包(com.common.aop)

定义注解:

package com.common.aop;
 
import java.lang.annotation.*;
 
/**
 * @description :
 * @auther Tyler
 * @date 2021/8/30
 */
 
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface IIdempotent {
}

 

注解实现

package com.common.aop;
 
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
 
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;
 
/**
 * @description :
 * @auther Tyler
 * @date 2021/8/30
 */
 
@Component
@Aspect
public class IdempotentAction {
 
    @Autowired
    HttpServletRequest request;
    public final static String ERROR_REPEATSUBMIT = "Repeated submission";
 
    //redis
    @Autowired
    protected StringRedisTemplate idempotentTemplate;
 
    @Pointcut("@annotation(com.tenyears.aop.IIdempotent)")
    private void controllerAspect() {
    }
 
    @Before("controllerAspect()")
    public void BeforeReturning(JoinPoint jp) throws Exception {
        IdempotentCheck(jp);
    }
 
    private void IdempotentCheck(JoinPoint jp) throws Exception {
//controller 名
        String controllerName = jp.getTarget().getClass().getName();
        Signature sig = jp.getSignature();
//方法名
        MethodSignature msig = (MethodSignature) sig;
        String method = msig.getMethod().getName();
//参数
        String body = NetUtil.getBodyString(request);
        //md5(Controller + method + body);
//md5 验证
        String signMD5= MD5.md5(controllerName+method+body);
        System.out.println("signMD5 :"+signMD5);
//存入redis 10秒过期
        if (Boolean.parseBoolean(idempotentTemplate.opsForValue().get(signMD5))) {
            throw new RuntimeException(ERROR_REPEATSUBMIT);
        } else {
            idempotentTemplate.opsForValue().set(signMD5, "true", 10, TimeUnit.SECONDS);
        }
 
    }
}
 
 
// netUtil.getBodyString方法
public static String getBodyString(ServletRequest request) {
        StringBuilder sb = new StringBuilder();
        InputStream inputStream = null;
        BufferedReader reader = null;
        try {
            inputStream = request.getInputStream();
            reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));
            String line = "";
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return sb.toString();
    }

 

 

二,项目中使用架包

application启动类

(重点,需要扫描架包,不然无法使用到!)

@SpringBootApplication
//必须要扫描到aop
@ComponentScan(basePackages={"com.common.aop"},lazyInit=true)
public class WebADApp {
    public static void main( String[] args )
    {
        SpringApplication.run(WebADApp.class, args);
 
    }
}

 

使用

@IIdempotent
    @RequestMapping(value = "test7", method = RequestMethod.POST)
    public void test7(ApiResult<String> req) {
 
        System.out.println(req.getData());
    }

 

posted @ 2021-08-30 16:03  正怒月神  阅读(63)  评论(0编辑  收藏  举报