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 returnDataInfoDTO = JSON.parseObject(jsonResponse, new TypeReference>() {}); // 从 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(); } } }