SSM+AOP保存操作日志到数据库表

操作日志表

CREATE TABLE `log` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '日志编号',
  `user_id` int(11) DEFAULT NULL COMMENT '操作者编号',
  `user_name` varchar(10) DEFAULT NULL COMMENT '操作者姓名',
  `ip` varchar(255) DEFAULT NULL COMMENT 'IP',
  `operate_content` varchar(255) DEFAULT NULL COMMENT '操作说明',
  `method` varchar(255) DEFAULT NULL COMMENT '方法名',
  `controller` varchar(255) DEFAULT NULL COMMENT '控制器名',
  `type` int(255) DEFAULT '1' COMMENT '日志类型(1无异常,2有异常)',
  `exmsg` varchar(255) DEFAULT NULL COMMENT '异常信息',
  `operate_time` datetime DEFAULT NULL COMMENT '操作时间',
  `parameters` longtext COMMENT '方法参数',
  `return_value` longtext COMMENT '返回值',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=51 DEFAULT CHARSET=utf8mb4;

操作日志的实体类,Mapper由mybatis生成器编写,Service,ServiceImpl自己编写
操作者实体类(与登陆模块的session中保存的登录者信息相关,这里已经省略getter和setter)


public class UserInfo {
	private long userId;
	private String userName;
	private String password;
}

在spring-mvc.xml中开启aop

  	<aop:aspectj-autoproxy/>
    <aop:config proxy-target-class="true"></aop:config>

自定义注解


@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface ArchivesLog {

    /**
     * 操作说明
     */
    public String operteContent() default "";

}


aop类



@Aspect
@Component
public class ArchivesLogAspect {
    @Autowired
    private LogService logService;

    private static final Logger logger = LoggerFactory.getLogger(ArchivesLog.class);

    @Pointcut("@annotation(com.framework.annotation.ArchivesLog)")
    public void controllerAspect() {
        //System.out.println("切入点...");
    }

    /**
     * 方法调用后触发 , 记录正常操作
     *
     * @param joinPoint
     * @throws ClassNotFoundException
     */
    @AfterReturning(value = "controllerAspect()", returning = "returnValue")
    public void after(JoinPoint joinPoint, Object returnValue) throws ClassNotFoundException, UnknownHostException {
        // 用户id
        int userId = (int) getUSerMsg().getUserId();
        String userName = getUSerMsg().getUserName();
        // 用户IP
        String ip = InetAddress.getLocalHost().getHostAddress();
        // 控制器名
        String targetName = getMethodDesc(joinPoint).getController();
        // 方法名
        String methodName = getMethodDesc(joinPoint).getMethod();
        // 操作说明
        String operteContent = getMethodDesc(joinPoint).getOperateContent();
        String parameters = Arrays.toString(removeServletObjects(joinPoint.getArgs()));
        String returnValueStr = (returnValue == null ? "null" : returnValue.toString());
        System.out.println("操作者:" + userName);
        System.out.println("操作说明:" + operteContent);
        System.out.println("方法参数:" + Arrays.toString(joinPoint.getArgs()));
        System.out.println("方法返回值:" + (returnValue == null ? "null" : returnValue.toString()));
        Log log = new Log();
        log.setParameters(parameters);
        log.setReturnValue(returnValueStr);
        log.setUserId(userId);
        log.setIp(ip);
        log.setOperateContent(operteContent);
        log.setMethod(methodName);
        log.setController(targetName);
        log.setOperateTime(new Date());
        log.setUserName(userName);
        logService.insertSelective(log);
    }

    /**
     * 发生异常,走此方法
     *
     * @param joinPoint
     * @param e
     */
    @AfterThrowing(pointcut = "controllerAspect()", throwing = "e")
    public void AfterThrowing(JoinPoint joinPoint, Throwable e) {
        try {
            // 用户id
            int userId = (int) getUSerMsg().getUserId();
//            操作者姓名
            String userName = getUSerMsg().getUserName();
            // 用户IP
            String ip = InetAddress.getLocalHost().getHostAddress();
            // 控制器名
            String targetName = getMethodDesc(joinPoint).getController();
            // 方法名
            String methodName = getMethodDesc(joinPoint).getMethod();
            // 操作说明
            String operteContent = getMethodDesc(joinPoint).getOperateContent();
            Log log = new Log();
            String exMsg = e.getCause().toString();
            String parameters = Arrays.toString(removeServletObjects(joinPoint.getArgs()));
            System.out.println("操作者:" + userName);
            System.out.println("操作说明:" + operteContent);
            System.out.println("方法参数:" + Arrays.toString(joinPoint.getArgs()));
            System.out.println("操作有异常:" + e.getCause().toString());
            if (exMsg != null) {
                int type = 2;
                log.setUserId(userId);
                log.setIp(ip);
                log.setOperateContent(operteContent);
                log.setParameters(parameters);
                log.setMethod(methodName);
                log.setController(targetName);
                log.setType(type);
                log.setExmsg(exMsg);
                log.setUserName(userName);
                logService.insertSelective(log);
            }
        } catch (Exception e1) {
            logger.error(e1.getMessage());
        }
    }

    /**
     * 获取 注解中对方法的描述
     *
     * @return
     * @throws ClassNotFoundException
     */
    public static Log 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;
                }
            }
        }
        Log log = new Log();
        log.setController(targetName);
        log.setMethod(methodName);
        log.setOperateContent(operteContent);
        return log;
    }

    /**
     * 得到用户信息
     *
     * @return
     */
    public static UserInfo getUSerMsg() {
        HttpServletRequest req = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        // 获取session
        HttpSession session = req.getSession();
//        从session中获取网站登录者信息
        UserInfo user = (UserInfo) session.getAttribute("userInfo");
        return user;
    }

    /*去掉方法参数的servlet对象*/
    public static Object[] removeServletObjects(Object[] objects) {
        List list = Arrays.asList(objects);
        list = new ArrayList(list);
        for (int i = 0; i < list.size(); i++) {
            Object object = list.get(i);
            if (object instanceof HttpServletResponse || object instanceof HttpServletRequest) {
                list.remove(object);
                i--;
            }
        }
        System.out.println(list);
        objects = list.toArray();
        return objects;
    }

}

在控制层的方法上加入注解

@ArchivesLog(operteContent = "退费")
    @RequestMapping(value = "/addPaymentRefund.html", method = RequestMethod.POST)
    public void addPaymentRefund(HttpServletRequest request,
                                 HttpServletResponse response,
                                 PaymentRefund paymentRefund) {

前端调用被注解了的方法
SSM+AOP保存操作日志到数据库表_第1张图片

数据库表中有了本次操作日志记录
在这里插入图片描述
参考链接

你可能感兴趣的:(SSM+AOP保存操作日志到数据库表)