[JAVA] springboot项目如何使用切面记录用户操作日志

1653 0
王子 2022-11-8 17:31:30 | 显示全部楼层 |阅读模式
目录

    1、引入springboot-aop集成jar2、application.yml中启用声明3、自定义一个拦截controller的注解4、自定义一个拦截service的注解5、定义日志记录切面6、开始使用
      1)@SystemControllerLog(description = "")2)用于监控service异常,可以不使用



1、引入springboot-aop集成jar

Spring-boot-start-aop

2、application.yml中启用声明
  1. #spring配置
  2. spring:
  3.   #切面启用
  4.   aop:
  5.     proxy-target-class: true
  6.     auto: true
复制代码
3、自定义一个拦截controller的注解
  1. package cn.annotation;
  2. import java.lang.annotation.*;
  3. /**
  4. * Title: SystemControllerLog
  5. * @date 2018年8月31日
  6. * @version V1.0
  7. * Description:  自定义注解,拦截controller
  8. */
  9. @Target({ElementType.PARAMETER, ElementType.METHOD})//作用在参数和方法上
  10. @Retention(RetentionPolicy.RUNTIME)//运行时注解
  11. @Documented//表明这个注解应该被 javadoc工具记录
  12. public @interface SystemControllerLog {
  13.     String description() default "";
  14. }
复制代码
4、自定义一个拦截service的注解
  1. package cn.annotation;
  2. import java.lang.annotation.*;
  3. /**
  4. * Title: SystemControllerLog
  5. * @date 2018年8月31日
  6. * @version V1.0
  7. * Description:  自定义注解,拦截service
  8. */
  9. @Target({ElementType.PARAMETER, ElementType.METHOD})
  10. @Retention(RetentionPolicy.RUNTIME)
  11. @Documented
  12. public @interface SystemServiceLog {
  13.     String description() default "";
  14. }
复制代码
5、定义日志记录切面
  1. package cn.annotation;
  2. import cn.pojo.Action;
  3. import cn.pojo.User;
  4. import cn.service.ActionService;
  5. import cn.utils.IpUtils;
  6. import cn.utils.JsonUtils;
  7. import org.aspectj.lang.JoinPoint;
  8. import org.aspectj.lang.annotation.AfterThrowing;
  9. import org.aspectj.lang.annotation.Aspect;
  10. import org.aspectj.lang.annotation.Before;
  11. import org.aspectj.lang.annotation.Pointcut;
  12. import org.slf4j.Logger;
  13. import org.slf4j.LoggerFactory;
  14. import org.springframework.stereotype.Component;
  15. import org.springframework.web.context.request.RequestContextHolder;
  16. import org.springframework.web.context.request.ServletRequestAttributes;
  17. import javax.annotation.Resource;
  18. import javax.servlet.http.HttpServletRequest;
  19. import javax.servlet.http.HttpSession;
  20. import java.lang.reflect.Method;
  21. import java.util.Date;
  22. /**
  23. * Title: SystemControllerLog
  24. * @date 2018年8月31日
  25. * @version V1.0
  26. * Description: 切点类
  27. */
  28. @Aspect
  29. @Component
  30. @SuppressWarnings("all")
  31. public class SystemLogAspect {
  32.     //注入Service用于把日志保存数据库,实际项目入库采用队列做异步
  33.     @Resource
  34.     private ActionService actionService;
  35.     //本地异常日志记录对象
  36.     private static final Logger logger = LoggerFactory.getLogger(SystemLogAspect.class);
  37.     //Service层切点
  38.     @Pointcut("@annotation(cn.annotation.SystemServiceLog)")
  39.     public void serviceAspect(){
  40.     }
  41.     //Controller层切点
  42.     @Pointcut("@annotation(cn.oa.annotation.SystemControllerLog)")
  43.     public void controllerAspect(){
  44.     }
  45.     /**
  46.      * @Description  前置通知  用于拦截Controller层记录用户的操作
  47.      * @date 2018年9月3日 10:38
  48.      */
  49.     @Before("controllerAspect()")
  50.     public void doBefore(JoinPoint joinPoint){
  51.         HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
  52.         HttpSession session = request.getSession();
  53.         //读取session中的用户
  54.         User user = (User) session.getAttribute("user");
  55.         String ip = IpUtils.getIpAddr(request);
  56.         try {
  57.             //*========控制台输出=========*//
  58.             System.out.println("==============前置通知开始==============");
  59.             System.out.println("请求方法" + (joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName()));
  60.             System.out.println("方法描述:" + getControllerMethodDescription(joinPoint));
  61.             System.out.println("请求人:"+user.getUsername());
  62.             System.out.println("请求ip:"+ip);
  63.             //*========数据库日志=========*//
  64.             Action action = new Action();
  65.             action.setActionDes(getControllerMethodDescription(joinPoint));
  66.             action.setActionType("0");
  67.             action.setActionIp(ip);
  68.             action.setUserId(user.getId());
  69.             action.setActionTime(new Date());
  70.             //保存数据库
  71.             actionService.add(action);
  72.         }catch (Exception e){
  73.             //记录本地异常日志
  74.             logger.error("==前置通知异常==");
  75.             logger.error("异常信息:{}",e.getMessage());
  76.         }
  77.     }
  78.     /**
  79.      * @Description  异常通知 用于拦截service层记录异常日志
  80.      * @date 2018年9月3日 下午5:43
  81.      */
  82.     @AfterThrowing(pointcut = "serviceAspect()",throwing = "e")
  83.     public void doAfterThrowing(JoinPoint joinPoint,Throwable e){
  84.         HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
  85.         HttpSession session = request.getSession();
  86.         //读取session中的用户
  87.         User user = (User) session.getAttribute("user");
  88.         //获取请求ip
  89.         String ip = IpUtils.getIpAddr(request);
  90.         //获取用户请求方法的参数并序列化为JSON格式字符串
  91.         String params = "";
  92.         if (joinPoint.getArgs()!=null&&joinPoint.getArgs().length>0){
  93.             for (int i = 0; i < joinPoint.getArgs().length; i++) {
  94.                 params+= JsonUtils.objectToJson(joinPoint.getArgs()[i])+";";
  95.             }
  96.         }
  97.         try{
  98.             /*========控制台输出=========*/
  99.             System.out.println("=====异常通知开始=====");
  100.             System.out.println("异常代码:" + e.getClass().getName());
  101.             System.out.println("异常信息:" + e.getMessage());
  102.             System.out.println("异常方法:" + (joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()"));
  103.             System.out.println("方法描述:" + getServiceMethodDescription(joinPoint));
  104.             System.out.println("请求人:" + user.getUsername());
  105.             System.out.println("请求IP:" + ip);
  106.             System.out.println("请求参数:" + params);
  107.             /*==========数据库日志=========*/
  108.             Action action = new Action();
  109.             action.setActionDes(getServiceMethodDescription(joinPoint));
  110.             action.setActionType("1");
  111.             action.setUserId(user.getId());
  112.             action.setActionIp(ip);
  113.             action.setActionTime(new Date());
  114.             //保存到数据库
  115.             actionService.add(action);
  116.         }catch (Exception ex){
  117.             //记录本地异常日志
  118.             logger.error("==异常通知异常==");
  119.             logger.error("异常信息:{}", ex.getMessage());
  120.         }
  121.     }
  122.     /**
  123.      * @Description  获取注解中对方法的描述信息 用于service层注解
  124.      * @date 2018年9月3日 下午5:05
  125.      */
  126.     public static String getServiceMethodDescription(JoinPoint joinPoint)throws Exception{
  127.         String targetName = joinPoint.getTarget().getClass().getName();
  128.         String methodName = joinPoint.getSignature().getName();
  129.         Object[] arguments = joinPoint.getArgs();
  130.                 Class targetClass = Class.forName(targetName);
  131.         Method[] methods = targetClass.getMethods();
  132.         String description = "";
  133.         for (Method method:methods) {
  134.             if (method.getName().equals(methodName)){
  135.                 Class[] clazzs = method.getParameterTypes();
  136.                 if (clazzs.length==arguments.length){
  137.                     description = method.getAnnotation(SystemServiceLog.class).description();
  138.                     break;
  139.                 }
  140.             }
  141.         }
  142.         return description;
  143.     }
  144.     /**
  145.      * @Description  获取注解中对方法的描述信息 用于Controller层注解
  146.      * @date 2018年9月3日 上午12:01
  147.      */
  148.     public static String getControllerMethodDescription(JoinPoint joinPoint) throws Exception {
  149.         String targetName = joinPoint.getTarget().getClass().getName();
  150.         String methodName = joinPoint.getSignature().getName();//目标方法名
  151.         Object[] arguments = joinPoint.getArgs();
  152.         Class targetClass = Class.forName(targetName);
  153.         Method[] methods = targetClass.getMethods();
  154.         String description = "";
  155.         for (Method method:methods) {
  156.             if (method.getName().equals(methodName)){
  157.                 Class[] clazzs = method.getParameterTypes();
  158.                 if (clazzs.length==arguments.length){
  159.                     description = method.getAnnotation(SystemControllerLog.class).description();
  160.                     break;
  161.                 }
  162.             }
  163.         }
  164.         return description;
  165.     }
  166. }
复制代码
6、开始使用


1)@SystemControllerLog(description = "")

注解加在控制器中方法上面,括号里写上操作描述



2)用于监控service异常,可以不使用
  1. @SystemServiceLog(description = "")
复制代码
注解加在service层方法上面,括号里写上操作描述
(此处为AOP拦截Service记录异常信息。方法不需要加try-catch)


以上为个人经验,希望能给大家一个参考,也希望大家多多支持中国红客联盟。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

中国红客联盟公众号

联系站长QQ:5520533

admin@chnhonker.com
Copyright © 2001-2025 Discuz Team. Powered by Discuz! X3.5 ( 粤ICP备13060014号 )|天天打卡 本站已运行