0


Java使用Aop实现用户操作日志记录(新手入门)

  1. 导入打印日志,aop,hutool,的依赖,Hutool是一个Java工具包,里面封装了大量的常用工具类,到时候咱们就通过这个工具包中有一个工具类可以用来获取客户端IP地址。<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId></dependency>``````<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId></dependency><dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.6.3</version></dependency>
  2. 自定义操作类型枚举类 因为基本是增删改查四个方法/** * 操作类型枚举类 * @author lichuan */public enum OperationTypeEnum { /** * 新增操作 */ INSERT("新增"), /** * 修改操作 */ UPDATE("修改"), /** * 删除操作 */ DELETE("删除"), /** * 查询操作 */ QUERY("查询"), /** * 其它 */ OTHER("其它"); private String operationType; OperationTypeEnum(String operationType) { this.operationType = operationType; } public String getOperationType() { return operationType; }}
  3. 自定义用来记录用户操作日志的注解@Target(ElementType.METHOD) //注解放置的目标位置,METHOD是可注解在方法级别上@Retention(RetentionPolicy.RUNTIME) //注解在哪个阶段执行@Documentedpublic @interface OperationLog { /** * 操作模块 * @return */ String operationModule() default ""; /** * 操作类型 * @return */ OperationTypeEnum operationType() default OperationTypeEnum.OTHER; /** * 操作说明 * @return */ String description() default "";}
  4. 写一个方法加上我们自定义的注解
  5. 定义用来记录用户操作日志的切面类
  1. import cn.hutool.extra.servlet.ServletUtil;
  2. import com.fasterxml.jackson.databind.ObjectMapper;
  3. import lombok.extern.slf4j.Slf4j;
  4. import org.aspectj.lang.ProceedingJoinPoint;
  5. import org.aspectj.lang.annotation.Around;
  6. import org.aspectj.lang.annotation.Aspect;
  7. import org.aspectj.lang.annotation.Pointcut;
  8. import org.aspectj.lang.reflect.MethodSignature;
  9. import org.springframework.stereotype.Component;
  10. import org.springframework.web.context.request.RequestAttributes;
  11. import org.springframework.web.context.request.RequestContextHolder;
  12. import javax.servlet.http.HttpServletRequest;
  13. import java.lang.reflect.Method;
  14. import java.util.HashMap;
  15. import java.util.Map;
  16. /**
  17. * @author lichuan
  18. */
  19. @Aspect
  20. @Component
  21. @Slf4j
  22. public class OperationLogAspect {
  23. /**
  24. * 设置操作日志切入点,在注解的位置切入代码
  25. */
  26. @Pointcut("execution(public * com.tm.controller..*Controller.*(..))")
  27. public void operationLogPointCut() {
  28. }
  29. /**
  30. * 定义环绕通知
  31. * 1. 环绕通知需要携带ProceedingJoinPoint类型的参数
  32. * 2. 环绕通知类似于动态代理的全过程ProceedingJoinPoint类型的参数可以决定是否执行目标方法
  33. * 3. 且环绕通知必须有返回值,返回值即目标方法的返回值
  34. */
  35. @Around("operationLogPointCut()")
  36. public Object around(ProceedingJoinPoint joinPoint) {
  37. Object result = null;
  38. //获取系统当前时间毫秒值
  39. long beginTime = System.currentTimeMillis();
  40. log.info("环绕通知开始");
  41. try {
  42. //执行目标方法
  43. result = joinPoint.proceed();
  44. } catch (Throwable e) {
  45. e.printStackTrace();
  46. }
  47. //获取系统当前时间毫秒值
  48. long endTime = System.currentTimeMillis();
  49. // 获取RequestAttributes
  50. RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
  51. // 从获取RequestAttributes中获取HttpServletRequest的信息
  52. HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);
  53. //获取ip
  54. String clientIP = ServletUtil.getClientIP(request);
  55. log.info(clientIP);
  56. //获取目标方法执行时间
  57. long usageTime = endTime - beginTime;
  58. // operationLogEntity.setUsageTime(usageTime);
  59. try {
  60. // 从切面织入点处通过反射机制获取织入点处的方法
  61. MethodSignature signature = (MethodSignature) joinPoint.getSignature();
  62. // 获取切入点所在的方法
  63. Method method = signature.getMethod();
  64. //System.out.println(method);
  65. // 获取操作
  66. OperationLog operationLog = method.getAnnotation(OperationLog.class);
  67. if (operationLog != null) {
  68. log.info(operationLog.operationModule());
  69. log.info(operationLog.description());
  70. log.info(operationLog.operationType().getOperationType());
  71. }
  72. // 获取请求的类名
  73. String className = joinPoint.getTarget().getClass().getName();
  74. // 获取请求的方法名
  75. String methodName = method.getName();
  76. methodName = className + "." + methodName;
  77. log.info(methodName);
  78. // 请求方法
  79. // operationLogEntity.setMethodName(methodName);
  80. // 请求的参数
  81. Map<String, String> parameterMap = ServletUtil.getParamMap(request);
  82. // 将参数所在的数组转换成json
  83. String requestParams = new ObjectMapper().writeValueAsString(parameterMap);
  84. // 请求参数
  85. System.out.println(parameterMap);
  86. log.info(requestParams);
  87. // 返回结果
  88. log.info(new ObjectMapper().writeValueAsString(result));
  89. // 请求URL
  90. log.info(request.getRequestURL().toString());
  91. // 请求URI
  92. log.info(request.getRequestURI());
  93. // 创建时间
  94. // operationLogEntity.setCreateTime(new Date());
  95. // System.out.println(operationLogEntity);
  96. log.info("环绕通知结束");
  97. } catch (Exception e) {
  98. }
  99. return result;
  100. }
  101. /**
  102. * 转换request 请求参数
  103. * @param parameterMap request获取的参数数组
  104. */
  105. public Map<String, String> convertParameterMap(Map<String, String[]> parameterMap) {
  106. Map<String, String> convertParameterMap = new HashMap<>();
  107. for (String key : parameterMap.keySet()) {
  108. convertParameterMap.put(key, parameterMap.get(key)[0]);
  109. }
  110. return convertParameterMap;
  111. }
  112. }

6.测试

调用test方法,可以看到控制台已经打印出了日志信息,创建表的对象存入即可

标签: java spring mybatis

本文转载自: https://blog.csdn.net/m0_56759222/article/details/129453592
版权归原作者 空指针异常z 所有, 如有侵权,请联系我们删除。

“Java使用Aop实现用户操作日志记录(新手入门)”的评论:

还没有评论