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()); }

浙公网安备 33010602011771号