SSM+AOP+spring_security实现日志功能并且保存到数据库中

这是在控制层实现日志系统的,之前是在service中实现的日志,垃圾的一批,还麻烦,自定义注解来实现日志功能很方便

操作日志表

CREATE TABLE `t_log` (
  `id` int(11) NOT NULL AUTO_INCREMENT 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 '控制器名',
  `operate_time` datetime DEFAULT NULL COMMENT '操作时间',
  `parameters` longtext COMMENT '方法参数',
  `return_value` longtext COMMENT '返回值',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=61 DEFAULT CHARSET=utf8mb4;

操作日志的实体类,mapper文件等自行解决

//用来保存用户信息的
@Data
public class UserInfo {
	private long userId;
	private String userName;
	private String password;
}
package com.itwangpt.pojo;

import java.io.Serializable;
import java.util.Date;

/**
 * @author 王鹏滔
 */
@Data
public class Log implements Serializable {
    private Integer id;
    private String parameters;
    private String returnValue;
    private String ip;
    private String operateContent;
    private String method;
    private String controller;
    private Date operateTime;
    private String userName;
}

在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类

package com.itwangpt.aop;

import com.itwangpt.annotation.ArchivesLog;
import com.itwangpt.pojo.Log;
import com.itwangpt.pojo.UserInfo;
import com.itwangpt.service.LogService;
import com.alibaba.dubbo.config.annotation.Reference;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.*;

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

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

    @Pointcut("@annotation(com.itwangpt.annotation.ArchivesLog)")
    public void controllerAspect() {
    }

    /**
     * 方法调用后触发 , 记录正常操作
     *
     * @param joinPoint
     * @throws ClassNotFoundException
     */
    @AfterReturning(value = "controllerAspect()", returning = "returnValue")
    public void after(JoinPoint joinPoint, Object returnValue) throws ClassNotFoundException, UnknownHostException, UnknownHostException {
        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.setIp(ip);
        log.setOperateContent(operteContent);
        log.setMethod(methodName);
        log.setController(targetName);
        log.setOperateTime(new Date());
        log.setUserName(userName);
        logService.insertLog(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.setIp(ip);
                log.setOperateContent(operteContent);
                log.setParameters(parameters);
                log.setMethod(methodName);
                log.setController(targetName);
                log.setUserName(userName);
                logService.insertLog(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() {
        UserDetails principal = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        String username="";
        String password="";
        if (principal!=null){
           username = principal.getUsername();
           password = principal.getPassword();
        }

        //从spring_security中获取信息
        UserInfo user = new UserInfo();
        user.setUserName(username);
        user.setPassword(password);
        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;
    }

}

在controller(控制层)方法上加注解

    @PreAuthorize("hasAuthority('CHECKITEM_EDIT')")
    @ArchivesLog(operteContent = "更新检查组")
    @RequestMapping("/updateCheckGroupEdit4ById")
    public Result updateCheckGroupEdit4ById(@RequestBody CheckGroup checkGroup){
        try {
           checkGroupService.updateCheckGroupEdit4ById(checkGroup);
            return Result.success(MessageConstant.EDIT_CHECKGROUP_SUCCESS);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error(MessageConstant.EDIT_CHECKGROUP_FAIL);
        }
    }

大家可以根据自己的需求更改

发布了3 篇原创文章 · 获赞 0 · 访问量 121

猜你喜欢

转载自blog.csdn.net/weixin_44990342/article/details/104358978