Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 9322|回复: 0

ssm 项目记录用户操作日志和异常日志

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-4-18 10:40:54 | 显示全部楼层 |阅读模式

    借助网上参考的内容,写出自己记录操作日志的心得!!

    我用的是ssm项目使用aop记录日志;这里用到了aop的切点 和 自定义注解方式;

    1、建好数据表:

      数据库记录的字段有: 日志id 、操作人、操作人IP、操作时间、操作方法、操作哪个控制层或者服务层、操作说明(记录用户操作的详情说明)、类型、异常信息

     

    2、在spring重配置如下:

      因为在spring里我配置了记录服务层的切点; 所以我在spring-mvc 里面 重新配置了一个可以扫描控制层的切点,使用的是cglib 代理:

      <!-- 启动AOP AspectJ注解自动代理 -->
      <aop:aspectj-autoproxy />
      <!-- 通知spring使用cglib而不是jdk的来生成代理方法 AOP可以拦截到Controller -->
      <aop:config proxy-target-class="true"></aop:config>

     

    3、接下来写自定义的注解 

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    @Documented
    public @interface ArchivesLog { /** * 操作说明 */ public String operteContent() default ""; }

     

    4、拿到切点的内容,并且在此存库

    package com.zhkj.jtpdms.log;
    
    import java.lang.reflect.Method; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import com.zhkj.jtpdms.entity.system.LogInfo; import com.zhkj.jtpdms.entity.system.User; import com.zhkj.jtpdms.service.system.LogInfoService; import com.zhkj.jtpdms.util.GlobalConstant; /** * 操作日志类 * * @author MEIM * */ @Aspect @Component public class ArchivesLogAspect { @Autowired private LogInfoService loginfoService; private static final Logger logger = LoggerFactory.getLogger(ArchivesLog.class); @Pointcut("@annotation(ArchivesLog)") public void controllerAspect() { //System.out.println("切入点..."); } /** * 方法调用后触发 , 记录正常操作 * * @param joinPoint * @throws ClassNotFoundException */ @AfterReturning("controllerAspect()") public void after(JoinPoint joinPoint) throws ClassNotFoundException { // 用户id int userId = getUSerMsg().getId(); // 用户IP String ip = getUSerMsg().getLoginIp(); // 控制器名 String targetName = getMethodDesc(joinPoint).getController(); // 方法名 String methodName = getMethodDesc(joinPoint).getMethod(); // 操作说明 String operteContent = getMethodDesc(joinPoint).getOperateContent(); LogInfo logInfo = new LogInfo(); logInfo.setUserId(userId); logInfo.setIp(ip); logInfo.setOperateContent(operteContent); logInfo.setMethod(methodName); logInfo.setController(targetName); loginfoService.insertLog(logInfo); } /** * 发生异常,走此方法 * @param joinPoint * @param e */ @AfterThrowing(pointcut = "controllerAspect()", throwing = "e") public void AfterThrowing(JoinPoint joinPoint, Throwable e) { try { // 用户id int userId = getUSerMsg().getId(); // 用户IP String ip = getUSerMsg().getLoginIp(); // 控制器名 String targetName = getMethodDesc(joinPoint).getController(); // 方法名 String methodName = getMethodDesc(joinPoint).getMethod(); // 操作说明 String operteContent = getMethodDesc(joinPoint).getOperateContent(); LogInfo logInfo = new LogInfo(); String exMsg = e.getCause().toString(); if (exMsg != null) { int type = 2; logInfo.setUserId(userId); logInfo.setIp(ip); logInfo.setOperateContent(operteContent); logInfo.setMethod(methodName); logInfo.setController(targetName); logInfo.setType(type); logInfo.setExMsg(exMsg); loginfoService.insertLog(logInfo); } } catch (Exception e1) { logger.error(e1.getMessage()); } } /** * 获取 注解中对方法的描述 * * @return * @throws ClassNotFoundException */ public static LogInfo getMethodDesc(JoinPoint joinPoint) throws ClassNotFoundException { String targetName = joinPoint.getTarget().getClass().getName(); String methodName = joinPoint.getSignature().getName(); Object[] arguments = joinPoint.getArgs(); Class targetClass = Class.forName(targetName); Method[] methods = targetClass.getMethods(); String operteContent = ""; for (Method method : methods) { if (method.getName().equals(methodName)) { Class[] clazzs = method.getParameterTypes(); if (clazzs.length == arguments.length) {
                // 操作说明 operteContent = method.getAnnotation(ArchivesLog.class).operteContent(); break; } } } LogInfo logInfo = new LogInfo(); logInfo.setController(targetName); logInfo.setMethod(methodName); logInfo.setOperateContent(operteContent); return logInfo; } /** * 得到用户信息 * * @return */ public static User getUSerMsg() { HttpServletRequest req = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); // 获取session HttpSession session = req.getSession(); User user = (User) session.getAttribute(GlobalConstant.SESSION_USER); return user; } }

     

    5、在控制层/服务层加上自定义注解即可成功

       @RequestMapping("/saveUser")
        @ResponseBody
      // 此处加上自定义注解 ,operteContent 是操作说明 @ArchivesLog(operteContent = "新增用户") public JsonResult saveUser(User user, String check) {
        //... 增加操作 
       }

     

    6、查看效果如下:

     

    7、注意事项:

         需要在spring-mvc  配置aop !!!

        通知的几个属性(@around , @before ,@after ,@afterRetruning,@afterThrowing)需要弄清楚!!

       还有不明白之处欢迎沟通!

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

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

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-5 10:48 , Processed in 0.056601 second(s), 30 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表