aspect操作日志
00 导入依赖
<!--aspect -->
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.13.2</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.5</version>
</dependency>
01 日志注解
package com.saiyou.annotation;
import com.saiyou.enums.BusinessType;
import java.lang.annotation.*;
/**
* 自定义操作日志注解
* @author lyn
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Log {
/**
* 模块
*
*/
String title() default"";
/**
* 功能
*
*/
BusinessType businesstype () default BusinessType.OTHER;
/**
* 是否保存请求参数
*
*/
boolean isSaveRequestData() default true;
}
02 操作日志记录处理(aspect)
package com.saiyou.aspect;
import cn.hutool.core.util.ObjectUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.saiyou.annotation.Log;
import com.saiyou.controller.interceptor.UserHolder;
import com.saiyou.entity.dto.LoginUserInfoDTO;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindingResult;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Objects;
/**
* 操作日志记录处理
* 描述: aop,aspect
*
* @author lyn
* @date 2022/3/4 14:42
*/
@Aspect
@Component
public class LogAspect {
/**
* 配置织入点
*/
@Pointcut("@annotation(com.saiyou.annotation.Log)")
public void logPointcut() {
}
/**
* 处理完请求后执行
*
* @param joinPoint 切点
* @param jsonResult 返回参数
*/
@AfterReturning(pointcut = "logPointcut()", returning = "jsonResult")
public void doAfterReturning(JoinPoint joinPoint, Object jsonResult) {
handleLog(joinPoint, null, jsonResult);
}
@AfterThrowing(pointcut = "logPointcut()", throwing = "e")
public void doAfterThrowing(JoinPoint joinPoint, Exception e) {
handleLog(joinPoint, e, null);
}
private void handleLog(JoinPoint joinPoint, Exception e, Object jsonResult) {
Log logAnnotation = getAnnotationLog(joinPoint);
if (Objects.isNull(logAnnotation)) {
return;
}
//从ThreadLocal中获取当前用户
LoginUserInfoDTO loginUser = UserHolder.get();
//记录操作人的信息(略)
//记录返回参数jsonResult
//获取日志注解中的信息
String title = logAnnotation.title();
//序号
int ordinal = logAnnotation.businesstype().ordinal();
if (Objects.isNull(e)) {
//记录错误信息
}
if (logAnnotation.isSaveRequestData()) {
//获取请求参数
String paramsStr = getRequestParam(joinPoint);
System.out.println(paramsStr);
}
//保存日志(异步or中间件)
}
/**
* 是否存在注解,如果存在就返回
*
* @param joinPoint
* @return
*/
private Log getAnnotationLog(JoinPoint joinPoint) {
//签名
Signature signature = joinPoint.getSignature();
//强转成方法签名
MethodSignature methodSignature = (MethodSignature) signature;
Method method = methodSignature.getMethod();
if (Objects.nonNull(method)) {
return method.getAnnotation(Log.class);
}
return null;
}
/**
* 获取请求的参数
*
* @param joinPoint
*/
private String getRequestParam(JoinPoint joinPoint) {
//如果方法是put或者是post 则按如下方式获取请求参数字符串
Object[] params = joinPoint.getArgs();
if (params != null) {
return argsArrayToString(params);
}
return null;
}
/**
* 参数拼装
*/
private String argsArrayToString(Object[] paramsArray) {
StringBuilder sbr = new StringBuilder("");
if (paramsArray != null && paramsArray.length > 0) {
for (int i = 0; i < paramsArray.length; i++) {
if (ObjectUtil.isNotNull(paramsArray[i]) && !isFilterObject(paramsArray[i])) {
//javaBean、列表数组转换为json字符串
String jsonObj = objToJson(paramsArray[i]);
sbr.append(jsonObj).append(" ");
}
}
}
return sbr.toString().trim();
}
/**
* 判断是否需要过滤的对象。(MultipartFile是过滤对象)
*
* @param o 对象信息。
* @return 如果是需要过滤的对象,则返回true;否则返回false。
*/
@SuppressWarnings("rawtypes")
public boolean isFilterObject(final Object o) {
Class<?> clazz = o.getClass();
if (clazz.isArray()) {
return clazz.getComponentType().isAssignableFrom(MultipartFile.class);
} else if (Collection.class.isAssignableFrom(clazz)) {
Collection collection = (Collection) o;
for (Iterator iter = collection.iterator(); iter.hasNext(); ) {
return iter.next() instanceof MultipartFile;
}
} else if (Map.class.isAssignableFrom(clazz)) {
Map map = (Map) o;
for (Iterator iter = map.entrySet().iterator(); iter.hasNext(); ) {
Map.Entry entry = (Map.Entry) iter.next();
return entry.getValue() instanceof MultipartFile;
}
}
return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse
|| o instanceof BindingResult;
}
private final static ObjectMapper objectMapper = new ObjectMapper();
/**
* javaBean、列表数组转换为json字符串
*/
public static String objToJson(Object obj) {
try {
return objectMapper.writeValueAsString(obj);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return null;
}
}