自定义注解MyLog
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author qingshi
* @date 2022/8/27 19:36
* info:自定义注解类: 后台管理接口
*/
@Target(ElementType.METHOD) //注解放置的目标位置,METHOD是可注解在方法级别上
@Retention(RetentionPolicy.RUNTIME) //注解在哪个阶段执行
@Documented //生成文档
public @interface MyLog {
/** 操作菜单 */
String menu() default "";
/** 操作事件 */
String value() default "";
}
在Controller层的接口加上自定义注解
@MyLog(value = "查询全部菜单权限列表",menu = "角色管理")
切面处理类
/**
* @author qingshi
* @date 2022/8/27 19:38
* info:系统日志:切面处理类
*/
@Component
@Aspect
public class SysLogAspect {
@Autowired
private RedisTemplate redisTemplate;
@Autowired
private EntityManager entityManager;
//定义切点 @Pointcut
//在注解的位置切入代码
@Pointcut("@annotation(com.cn.ih.java.main.config.MyLog)")//此处是自定义注解所在的路径
public void logPoinCut() {
}
//环绕通知
@Around("logPoinCut()")
public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
Object result = null;
String methodName = proceedingJoinPoint.getSignature().getName();
//从切面织入点处通过反射机制获取织入点处的方法
MethodSignature signature = (MethodSignature) proceedingJoinPoint.getSignature();
//获取切入点所在的方法
Method method = signature.getMethod();
//获取操作--方法上的Log的值
MyLog myLog = method.getAnnotation(MyLog.class);
String value=myLog.value();//获取自定义注解的值
//获取方法参数值数组
Object[] args = proceedingJoinPoint.getArgs();
//得到其方法签名
MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature();
String username=null;
try {
//获取请求头
HttpServletRequest requests = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
//从请求头中获取需要的参数
String token = requests.getHeader("token");
if (!ObjectUtils.isEmpty(redisTemplate.opsForValue().get(token))) {
//从redis中获取token对应的name(在登录接口存入redis)
username = (String) redisTemplate.opsForValue().get(token);
}else {
//token已失效,请重新登陆
}
if (getRequestParams(proceedingJoinPoint).size()!=0) {
//获取方法参数类型数组
Class[] paramTypeArray = methodSignature.getParameterTypes();
if (!StringUtils.isEmpty(paramTypeArray)) {
if (EntityManager.class.isAssignableFrom(paramTypeArray[paramTypeArray.length - 1])) {
//如果方法的参数列表最后一个参数是entityManager类型,则给其赋值
args[args.length - 1] = entityManager;
}
String request = new Gson().toJson(args).substring(1, new Gson().toJson(args).length() - 1);
result = proceedingJoinPoint.proceed(args);
logger.info("后台管理方法---" + proceedingJoinPoint.getSignature().getName() +"---"+value+"---请求用户---"+username+"---请求参数---" + request + "\n---响应参数---"+ result);
}
}else {
Map<String, Object> requestParams = getRequestParams(proceedingJoinPoint);
result = proceedingJoinPoint.proceed(args);
logger.info("后台管理方法---" + proceedingJoinPoint.getSignature().getName() +"---"+value+"---请求用户---"+username+"---请求参数---" + requestParams + "\n---响应参数---"+ result);
}
}catch (Exception e){
//进入异常是因为请求头获取失败,此处可以执行自己的业务逻辑,也可以继续打印日志
if (getRequestParams(proceedingJoinPoint).size()!=0) {
//获取方法参数类型数组
Class[] paramTypeArray = methodSignature.getParameterTypes();
if (!StringUtils.isEmpty(paramTypeArray)) {
if (EntityManager.class.isAssignableFrom(paramTypeArray[paramTypeArray.length - 1])) {
//如果方法的参数列表最后一个参数是entityManager类型,则给其赋值
args[args.length - 1] = entityManager;
}
String request = new Gson().toJson(args).substring(1, new Gson().toJson(args).length() - 1);
result = proceedingJoinPoint.proceed(args);
logger.info("后台管理方法---" + proceedingJoinPoint.getSignature().getName() +"---"+value+"---请求用户---"+username+"---请求参数---" + request + "\n---响应参数---"+ result);
}
}else {
Map<String, Object> requestParams = getRequestParams(proceedingJoinPoint);
result = proceedingJoinPoint.proceed(args);
logger.info("后台管理方法---" + proceedingJoinPoint.getSignature().getName() +"---"+value+"---请求用户---"+username+"---请求参数---" + requestParams + "\n---响应参数---"+ result);
}
}
return result;
}
private Map<String, Object> getRequestParams(ProceedingJoinPoint proceedingJoinPoint) {
Map<String, Object> requestParams = new HashMap<>();
//参数名
String[] paramNames = ((MethodSignature)proceedingJoinPoint.getSignature()).getParameterNames();
//参数值
Object[] paramValues = proceedingJoinPoint.getArgs();
for (int i = 0; i < paramNames.length; i++) {
Object value = paramValues[i];
//如果是文件对象
if (value instanceof MultipartFile) {
MultipartFile file = (MultipartFile) value;
value = file.getOriginalFilename(); //获取文件名
}
requestParams.put(paramNames[i], value);
}
return requestParams;
}
}