package com.mzl.flower.base.aspect;
|
|
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.TypeReference;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.mzl.flower.base.ReturnDataInfoDTO;
|
import com.mzl.flower.base.annotation.OperationLog;
|
import com.mzl.flower.entity.log.OperationRecord;
|
import com.mzl.flower.mapper.log.OperationRecordMapper;
|
import org.aspectj.lang.ProceedingJoinPoint;
|
import org.aspectj.lang.annotation.Around;
|
import org.aspectj.lang.annotation.Aspect;
|
import org.aspectj.lang.annotation.Pointcut;
|
import org.aspectj.lang.reflect.MethodSignature;
|
import org.springframework.http.ResponseEntity;
|
import org.springframework.stereotype.Component;
|
import org.springframework.util.ObjectUtils;
|
import org.springframework.web.context.request.RequestContextHolder;
|
import org.springframework.web.context.request.ServletRequestAttributes;
|
import javax.annotation.Resource;
|
import javax.servlet.http.HttpServletRequest;
|
import java.lang.reflect.Method;
|
import java.util.Date;
|
|
import static com.mzl.flower.utils.IpUtil.getIpAddress;
|
|
|
@Aspect
|
@Component
|
public class OperationLogAspect {
|
|
|
@Resource
|
private OperationRecordMapper operationRecordMapper;
|
|
//扫描使用这个注解的方法
|
@Pointcut("@annotation(com.mzl.flower.base.annotation.OperationLog)")
|
public void logPointCut() {
|
}
|
|
@Around("logPointCut()")
|
public Object around(ProceedingJoinPoint point) throws Throwable {
|
Date beginTime = new Date();
|
String result = null;
|
String status = null;
|
//执行代码,都加try catch,即使出错也不能影响主进程
|
OperationRecord operationRecord = null;
|
try {
|
Object obj = point.proceed();//放行请求的主进程并拿到返回值
|
if (obj != null) {
|
ResponseEntity<?> responseEntity = (ResponseEntity<?>) obj;
|
Object body = responseEntity.getBody();
|
// 将obj转换为String类型
|
String jsonResponse = JSONObject.toJSONString(body);
|
System.out.println(jsonResponse);
|
// 创建ObjectMapper实例
|
ObjectMapper objectMapper = new ObjectMapper();
|
// 使用 TypeReference 指定泛型类型
|
ReturnDataInfoDTO<Object> returnDataInfoDTO = JSON.parseObject(jsonResponse, new TypeReference<ReturnDataInfoDTO<Object>>() {});
|
// 从 ReturnDataInfoDTO 对象中获取 OperationRecord 对象
|
operationRecord = (OperationRecord) returnDataInfoDTO.getInfo();
|
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
if (attributes != null) {
|
HttpServletRequest request = attributes.getRequest();
|
// 获取请求的IP地址
|
String ip = getIpAddress(request);
|
operationRecord.setIpAddress(ip);
|
System.out.println("ip"+ip);
|
}
|
// if (attributes != null) {
|
// HttpServletRequest request = attributes.getRequest();
|
// System.out.println(request.getRemoteAddr()); // 或者使用上面提到的方法获取真实IP地址
|
// }
|
}
|
status = "success";
|
return obj;
|
} catch (Exception e) {//请求执行出错
|
result = e.getMessage();
|
status = "error";
|
throw e;
|
} finally {//无论成功失败,都保存下日志
|
saveLog(point, beginTime, new Date(), result, status, operationRecord);
|
}
|
}
|
|
//保存日志
|
private void saveLog(ProceedingJoinPoint joinPoint, Date beginTime, Date endTime, String result, String status, OperationRecord operationRecord) {
|
if (!ObjectUtils.isEmpty(operationRecord)) {
|
try {
|
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
Method method = signature.getMethod();
|
OperationLog annotation = method.getAnnotation(OperationLog.class);
|
operationRecord.setStatus(status);
|
if (annotation != null) {
|
//注解上的描述
|
String type = annotation.type();
|
// if (!StringUtils.isEmpty(type)) {
|
// String recordModule = operationRecordMapper.getCodeType("OPERATION_RECORD_MODULE", type);
|
// operationRecord.setModule(recordModule);
|
// } else {
|
operationRecord.setModule(type);
|
// }
|
operationRecord.setFunction(annotation.value());//注解类型
|
}//记录入参
|
// if (joinPoint.getArgs() != null) {
|
// try {
|
// operationRecord.setContent(JSONObject.toJSONString(result));
|
// } catch (Exception e) {
|
// e.printStackTrace();
|
// }
|
// }
|
//如果注解类型是1(增删改)或者是2(查询)报错,记录返回值,如果是查询正常就不记录,有可能返回值太多
|
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
//启动一个线程,执行报错日志,防止影响主请求
|
new Thread(() -> {
|
try {//保存数据到数据库
|
operationRecordMapper.insert(operationRecord);
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
}).start();
|
}
|
}
|
}
|