擷取swagger APIOperation上的注解,進行記錄檔輸出,非常友善。
1.自定義注解
//指明了修飾的這個注解的使用範圍,即被描述的注解可以用在哪裡
@Target(ElementType.METHOD)
//指明修飾的注解的生存周期,即會保留到哪個階段(RUNTIME: 運作級别保留,編譯後的class檔案中存在,在jvm運作時保留,可以被反射調用)
@Retention(RetentionPolicy.RUNTIME)
//指明修飾的注解,可以被例如javadoc此類的工具文檔化,隻負責标記,沒有成員取值
@Documented
public @interface RecordLog {
}
2.切面類
@Component
//把目前類辨別為一個切面供容器讀取
@Aspect
public class LogAspect {
@Resource
private SystemLogRepository logRepository;
//用戶端請求,大部分資訊可以在這裡面擷取到
@Resource
private HttpServletRequest request;
//将添加了RecordLog這個注解的地方作為一個切入點
@Pointcut("@annotation(com.xxx.RecordLog)")
public void logPointCut() {
}
/**
* 方法正常退出時執行
*/
@AfterReturning(pointcut = "logPointCut()")
public void doAfterReturning(JoinPoint joinPoint) {
try {
saveLog(joinPoint, null);
} catch (Exception e) {
e.printStackTrace();
}
}
//這個方法用于對切面擷取到的資料進行處理,根據實際應用場景可以選擇存到資料庫或者列印到日志檔案中
private void saveLog(JoinPoint joinPoint, String e) throws Exception {
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
Method method = methodSignature.getMethod();
//擷取ApiOperation注解的value,同樣的方法可以擷取你加在切入點方法上的注解的各種參數
ApiOperation annotation = method.getAnnotation(ApiOperation.class);
String userId = request.getParameter("userId");
SystemOperationLog operationLog = new SystemOperationLog();
operationLog.setOperationId(UUID.randomUUID().toString().replace("-", ""));
operationLog.setTitle(annotation.value());
//擷取請求方法(POST、GET等)
operationLog.setBusinessType(request.getMethod());
//擷取方法名
operationLog.setOperationMethod(methodSignature.getName());
operationLog.setUserId(userId);
operationLog.setUrl(request.getRequestURL().toString());
//擷取調用方本地ip位址
operationLog.setUserIp(InetAddress.getLocalHost().getHostAddress());
//擷取請求參數并轉換成json格式
operationLog.setOperationParam(JSON.toJSONString(joinPoint.getArgs()));
operationLog.setStatus(e == null ? 0 : 1);
operationLog.setErrorMessage(e);
operationLog.setOperationTime(new Date());
logRepository.save(operationLog);
}
/**
* 方法抛出異常時執行
*/
@AfterThrowing(pointcut = "logPointCut()", throwing = "exception")
public void doAfterThrowing(JoinPoint joinPoint, Exception exception) {
try {
saveLog(joinPoint, exception.getMessage());
} catch (Exception e) {
e.printStackTrace();
}
}
}
本篇文章中隻用到了doAfterThrowing和doAfterReturning,通常根據業務場景選擇切面方法在什麼時候執行,以後用到其他場景再來更新
參考文章:
https://www.cnblogs.com/hyc-ana/p/9325618.html
https://www.cnblogs.com/jap6/p/10637429.html
https://blog.csdn.net/fz13768884254/article/details/83538709