ssm环境下基于aop的日志记录

该日志记录背景是后台权限管理系统,日志主要记录用户姓名,访问时间,访问时长,访问路径,访问方法名和访问ip。

主要技术是反射和springAop
首先创建一个日志实体类,用于封装数据并存入数据库。

public class SysLog {
    private String id;
    private Date visitTime;
    private String visitTimeStr;
    private String username;
    private String ip;
    private String url;
    private Long executionTime;
    private String method;
    //get和set方法忽略
    }

然后配置切面类,注解aop已开启。切入点为controller包下所有类的方法。
下面代码是一段一段截取的,拼在一起就是一个完整的切面类。
request用于获取ip,sysLogService用于调用存储日志。

@Component
@Aspect
public class logAop {
    @Pointcut("execution(* com.itcc.controller.*.*(..))")
    public void p1() {

    }
    @Autowired
    private HttpServletRequest request;
    @Autowired
    private ISysLogService sysLogService;

    private Date visitTime;//访问时间
    private Class clazz;//访问的类
    private Method method;//访问的方法

接着配置前置通知,运用反射获取访问类和方法,方法分为有参方法和无参方法,一个只需要方法名而另一个不但要方法名,还需要参数的类对象。

//前置通知  主要是获取开始时间,执行的类是哪一个,执行的是哪一个方法
    @Before("p1()")
    public void dobefore(JoinPoint jp) throws NoSuchMethodException {
        //获取当前时间
        visitTime = new Date();
        //获取当前类名
        clazz = jp.getTarget().getClass();
        //获取当前方法名
        String methodName = jp.getSignature().getName();
        //获取当前方法参数
        Object[] args = jp.getArgs();
        if (args != null && args.length <= 0) {
            //无参构造
            method = clazz.getMethod(methodName);
        } else {
        	//有参构造
            Class[] argsClass = new Class[args.length];
            for (int i = 0; i < args.length; i++) {
                argsClass[i] = args[i].getClass();
            }
            method = clazz.getMethod(methodName, argsClass);
        }

    }

最后配置后置通知。后置通知主要获取访问时长,访问路径,访问人姓名和访问ip,然后封装日志对象并存储。
这里获取访问路径方法主要是获取类和方法上RequestMapping的value值,然后拼接成路径。
系统使用了spring security框架,所以访问姓名通过SecurityContext获取。
getAuthentication()来获取认证,.getPrincipal()来获取认证的对象。

@After("p1()")
    public void doAfter(JoinPoint jp) throws Exception {
        //获取访问时长
        long executionTime = new Date().getTime() - visitTime.getTime();
        String url = "";
        //获取url
        //获取类上的路径 @RequestMapping("/role")
        if (clazz != null && method != null && clazz != SysLogController.class) {
            RequestMapping clazzAnnotation = (RequestMapping) clazz.getAnnotation(RequestMapping.class);
            if (clazzAnnotation != null) {
                String[] clazzValue = clazzAnnotation.value();
		//获取方法上的路径 @RequestMapping("/findAll")
                RequestMapping methodAnnotation = method.getAnnotation(RequestMapping.class);
                if (methodAnnotation != null) {
                    String[] methodValue = methodAnnotation.value();
                    url = clazzValue[0] + methodValue[0];

                    //获取ip
                    String ip = request.getRemoteAddr();
                    //获取操作者用户名
                    SecurityContext context = SecurityContextHolder.getContext();
                    User user = (User) context.getAuthentication().getPrincipal();
                    String username = user.getUsername();

                    //封装syslog
                    SysLog sysLog = new SysLog();
                    sysLog.setExecutionTime(executionTime);
                    sysLog.setIp(ip);
                    sysLog.setMethod("[类名]"+clazz.getName()+"[方法名]"+method.getName());
                    sysLog.setUrl(url);
                    sysLog.setUsername(username);
                    sysLog.setVisitTime(visitTime);

                    //存储日志
                    sysLogService.save(sysLog);
                }
            }

        }

    }
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值