aop实现接口幂等性
1:aop处理逻辑:根据参数序列号判断是否继续执行接口,并记录请求信息
2:接口验证
根据参数序列号判断,并记录请求信息
/**
* 环绕通知 拦截指定的切点,这里拦截所有controller请求 切入点根据具体的接口判断
*/
@Around("execution(* com.wk.controller.*.*(..))")
@Order(Ordered.HIGHEST_PRECEDENCE)//前置执行
public Object interceptorRequest(ProceedingJoinPoint pj) throws Throwable {
long start = System.currentTimeMillis();
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
String requestURI = request.getRequestURI();
Object[] args = pj.getArgs();
List<Object> list = new ArrayList<>();
try {
//幂等实现,根据订单号去记录表查询,查询到直接返回,否则继续执行接口逻辑
String orderId = request.getParameter("orderId");
String inter = requestURI.startsWith("/") ? requestURI.substring(1) : requestURI;
String str = "addOrder,addUser";//需要幂等的接口,可配置在数据库
System.out.println("orderId=" + orderId + ",str=" + str+ ",inter=" + inter);
if (StringUtils.isNoneBlank(orderId) && StringUtils.isNoneBlank(inter) && str.contains(inter)) {
CrmLogMessage log = testService.getOrderId(orderId);
if (log == null) {
if (ArrayUtils.isNotEmpty(args)) {
for (Object arg : args) {
if (arg instanceof HttpServletResponse) {
continue;
} else if (arg instanceof HttpServletRequest) {
String source = ((HttpServletRequest) arg).getHeader("source");
} else {
list.add(arg);
}
}
}
String input = JSONArray.toJSONString(list, SerializerFeature.WriteNullStringAsEmpty);
//执行接口逻辑,并记录结果
Object proceed = pj.proceed(args);
long end = System.currentTimeMillis();
String output = JSONArray.toJSONString(proceed, SerializerFeature.WriteNullStringAsEmpty);
System.out.println("output:" + output);
CrmLogMessage log1 = new CrmLogMessage();
log1.setContent(input);
log1.setLogid(snowflakeIdWorker.workerId);
log1.setDateTime(end - start);
log1.setResult(output);
log1.setRequestUrl(requestURI);
log1.setRemarks(orderId);//订单表示
System.out.println("CrmLogMessage:" + log1.toString());
testService.insert(log1);
return proceed;
} else {//存在幂等直接返回
String result = log.getResult();
return result;
}
}
// 不需要幂等的接口,直接请求接口
} catch (Exception e) {
// 异常处理记录日志..log.error(e);
throw e;
}
return pj.proceed(args);
}
接口验证
@GetMapping("/addOrder")
public String addorder(String orderId,HttpServletRequest request){
System.out.println(" addorder start");
CrmLogMessage log = new CrmLogMessage();
testService.insert(log);
System.out.println(" addorder end");
return "ok";
}
验证结果
https://blog.csdn.net/qq_17231297/article/details/113449397?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1-113449397-blog-96765193.pc_relevant_default&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1-113449397-blog-96765193.pc_relevant_default&utm_relevant_index=2