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

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

我用的是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)需要弄清楚!!

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

posted @ 2019-01-07 10:30  MeiMeng  阅读(3937)  评论(2编辑  收藏  举报