Spring Boot AOP记录用户操作日志

Spring Boot AOP记录用户操作日志,通联数据java面试 ojdbc6 11.2.0.4 com.alibaba druid-spring-boot-starter 1.1.6 application.yml server: context-path: /web port: 7002 spring: datasource: druid: 数据库访问配置, 使用druid数据源 type: com.alibaba.druid.pool.DruidDataSource driver-class-name: oracle.jdbc.driver.OracleD 阅读详情

在Spring框架中,使用AOP配合自定义注解可以方便的实现用户操作的监控。首先搭建一个基本的Spring Boot Web环境开启Spring Boot,然后引入必要依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>

<!-- aop依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

<!-- oracle驱动 -->
<dependency>
   <groupId>com.oracle</groupId>
   <artifactId>ojdbc6</artifactId>
   <version>6.0</version>
</dependency>

<!-- druid数据源驱动 -->
<dependency>
   <groupId>com.alibaba</groupId>
   <artifactId>druid-spring-boot-starter</artifactId>
   <version>1.1.6</version>
</dependency>

自定义注解

定义一个方法级别的@Log注解,用于标注需要监控的方法:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {
    String value() default "";
}

创建库表和实体

在数据库中创建一张sys_log表,用于保存用户的操作日志,数据库采用oracle 11g:

CREATE TABLE "SCOTT"."SYS_LOG" (
   "ID" NUMBER(20) NOT NULL ,
   "USERNAME" VARCHAR2(50 BYTE) NULL ,
   "OPERATION" VARCHAR2(50 BYTE) NULL ,
   "TIME" NUMBER(11) NULL ,
   "METHOD" VARCHAR2(200 BYTE) NULL ,
   "PARAMS" VARCHAR2(500 BYTE) NULL ,
   "IP" VARCHAR2(64 BYTE) NULL ,
   "CREATE_TIME" DATE NULL 
);

COMMENT ON COLUMN "SCOTT"."SYS_LOG"."USERNAME" IS '用户名';
COMMENT ON COLUMN "SCOTT"."SYS_LOG"."OPERATION" IS '用户操作';
COMMENT ON COLUMN "SCOTT"."SYS_LOG"."TIME" IS '响应时间';
COMMENT ON COLUMN "SCOTT"."SYS_LOG"."METHOD" IS '请求方法';
COMMENT ON COLUMN "SCOTT"."SYS_LOG"."PARAMS" IS '请求参数';
COMMENT ON COLUMN "SCOTT"."SYS_LOG"."IP" IS 'IP地址';
COMMENT ON COLUMN "SCOTT"."SYS_LOG"."CREATE_TIME" IS '创建时间';

CREATE SEQUENCE seq_sys_log START WITH 1 INCREMENT BY 1;

库表对应的实体:

public class SysLog implements Serializable{

    private static final long serialVersionUID = -6309732882044872298L;
    
    private Integer id;
    private String username;
    private String operation;
    private Integer time;
    private String method;
    private String params;
    private String ip;
    private Date createTime;
    // get,set略
}

保存日志的方法

为了方便,这里直接使用Spring JdbcTemplate来操作数据库。定义一个SysLogDao接口,包含一个保存操作日志的抽象方法:

public interface SysLogDao {
    void saveSysLog(SysLog syslog);
}

其实现方法:

@Repository
public class SysLogDaoImp implements SysLogDao {

    @Autowired
    private JdbcTemplate jdbcTemplate;
    
    @Override
    public void saveSysLog(SysLog syslog) {
        StringBuffer sql = new StringBuffer("insert into sys_log ");
        sql.append("(id,username,operation,time,method,params,ip,create_time) ");
        sql.append("values(seq_sys_log.nextval,:username,:operation,:time,:method,");
        sql.append(":params,:ip,:createTime)");
        
        NamedParameterJdbcTemplate npjt = new NamedParameterJdbcTemplate(this.jdbcTemplate.getDataSource());
        npjt.update(sql.toString(), new BeanPropertySqlParameterSource(syslog));
    }
}

切面和切点

定义一个LogAspect类,使用@Aspect标注让其成为一个切面,切点为使用@Log注解标注的方法,使用@Around环绕通知:

@Aspect
@Component
public class LogAspect {

    @Autowired
    private SysLogDao sysLogDao;
    
    @Pointcut("@annotation(com.springboot.annotation.Log)")
    public void pointcut() { }

    @Around("pointcut()")
    public Object around(ProceedingJoinPoint point) {
        Object result = null;
        long beginTime = System.currentTimeMillis();
        try {
            // 执行方法
            result = point.proceed();
        } catch (Throwable e) {
            e.printStackTrace();
        }
        // 执行时长(毫秒)
        long time = System.currentTimeMillis() - beginTime;
        // 保存日志
        saveLog(point, time);
        return result;
    }

    private void saveLog(ProceedingJoinPoint joinPoint, long time) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        SysLog sysLog = new SysLog();
        Log logAnnotation = method.getAnnotation(Log.class);
        if (logAnnotation != null) {
            // 注解上的描述
            sysLog.setOperation(logAnnotation.value());
        }
        // 请求的方法名
        String className = joinPoint.getTarget().getClass().getName();
        String methodName = signature.getName();
        sysLog.setMethod(className   "."   methodName   "()");
        // 请求的方法参数值
        Object[] args = joinPoint.getArgs();
        // 请求的方法参数名称
        LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer();
        String[] paramNames = u.getParameterNames(method);
        if (args != null && paramNames != null) {
            String params = "";
            for (int i = 0; i < args.length; i  ) {
                params  = "  "   paramNames[i]   ": "   args[i];
            }
            sysLog.setParams(params);
        }
        // 获取request
        HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
        // 设置IP地址
        sysLog.setIp(IPUtils.getIpAddr(request));
        // 模拟一个用户名
        sysLog.setUsername("mrbird");
        sysLog.setTime((int) time);
        sysLog.setCreateTime(new Date());
        // 保存系统日志
        sysLogDao.saveSysLog(sysLog);
    }
}

测试

TestController:

@RestController
public class TestController {

    @Log("执行方法一")
    @GetMapping("/one")
    public void methodOne(String name) { }
    
    @Log("执行方法二")
    @GetMapping("/two")
    public void methodTwo() throws InterruptedException {
        Thread.sleep(2000);
    }
    
    @Log("执行方法三")
    @GetMapping("/three")
    public void methodThree(String name, String age) { }
}

最终项目目录如下图所示:

QQ截图20171208113619.png

启动项目,分别访问:

  • http://localhost:8080/web/one?name=KangKang
  • http://localhost:8080/web/two
  • http://localhost:8080/web/three?name=Mike&age=25

查询数据库:

SQL> select * from sys_log order by id;

        ID USERNAME   OPERATION        TIME METHOD                         PARAMS                         IP         CREATE_TIME
---------- ---------- ---------- ---------- ------------------------------ ------------------------------ ---------- --------------
        11 mrbird     执行方法一          6 com.springboot.controller.Test  name: KangKang                127.0.0.1  08-12月-17
                                            Controller.methodOne()

        12 mrbird     执行方法二       2000 com.springboot.controller.Test                                127.0.0.1  08-12月-17
                                            Controller.methodTwo()

        13 mrbird     执行方法三          0 com.springboot.controller.Test  name: Mike age: 25            127.0.0.1  08-12月-17
                                            Controller.methodThree()

source code

本文由博客一文多发平台 OpenWrite 发布!

计算机组成与系统结构(第三版) 袁春风主编 课后习题答案讲解 第一、二章 计算机系统概述 数据的机器级表示 阅读详情

相关推荐

别再为授权费头疼了!手把手教你免授权搞定西门子、马扎克等12种主流数控机床的数据采集

本文提供了一套免授权采集西门子、马扎克等12种主流数控机床数据的实战指南,帮助中小型机加工车间节省80%以上的采集成本。通过TCP/UDP协议逆向工程和跨平台数据整合,实现经济、灵活且可持续的数据采集方案,涵盖设备兼容性处理、数据频率优化等关键问题。

weixin_26873711的博客 709

写了一个关于SpringAop记录用户操作的功能

各位开发人员如果在公司一定要写关于建表注释,方便同事观看,对于自己来说是最基础的代码素养,对于自己的职业来说这是职业最基本的规范。当然如果是那样的,对吧,懂的都懂。2:创建自定义注解,自定义注解在很多的时候都会有用,例如日志审计,权限控制,数据校验,API文档生产,事务与缓存控制,代码生成与测试等等。5:关于Token 还有 Ip 工具类,时间工具类等获取的方式可以在很多的地方有!3:因为我这次写的是一个模块监控,监控当前登录人进行了哪些操作。1:先思考自己的需要记录什么功能,创建对应的数据库表。

我有一张床的博客 340

用Matlab系统辨识工具箱搞定温控系统建模:从阶跃响应到传递函数(附完整代码)

本文详细介绍了如何使用Matlab系统辨识工具箱进行温控系统建模,从阶跃响应数据采集到传递函数参数辨识的全过程。通过实际案例和完整代码,帮助工程师快速掌握PID控制参数整定技巧,提升温控系统设计效率。特别适合单片机开发者和自动化控制工程师参考。

weixin_30736301的博客 310

Spring Boot 使用AOP(环绕通知)完成对用户操作的日志记录

Spring Boot 使用AOP(环绕通知)完成对用户操作的日志记录,步骤超详细

怪咖@的博客 4302

基于QGIS的DEM地形数据精细化处理:从裁剪、合并到成果输出

本文详细介绍了使用QGIS进行DEM地形数据的精细化处理流程,包括数据获取、裁剪、合并及成果输出等关键步骤。通过实战技巧和注意事项,帮助用户高效处理地形数据,适用于GIS分析、三维建模等应用场景。

weixin_29093017的博客 452

Centos7.6下安装Zabbix6

一、

Overmaster博客 1906

【Springboot】基于AOP实现操作日志记录

基于AOP实现springboot项目中中的操作日志记录功能

ASL2915的博客 2681

S7-200SMART通过表格指令实现模拟量信号滑动平均值滤波的具体方法

S7-200SMART通过表格指令实现模拟量信号滑动平均值滤波的具体方法

Robot_PLC_HMI_Automation 6728

oracle中创建系统日志的使用

sql: 创建序列序列序列系统日志,以1乘以1开始 CREATE SEQUENCE seq_sys_log START WITH 1 INCREMENT BY 1; 1、sequence的基本用法: [sql]view plaincopy createsequenceSEQ_ON_USER minvalue1 maxvalue999999999...

mysky_xu的博客 919

ESP-IDF OTA升级过程中遇到的“esp_transport_read returned:-1 and errno:128”问题(4)

ESP-IDF OTA升级过程中遇到的“esp_transport_read returned:-1 and errno:128”问题(4)

phmatthaus的专栏 1534

QGIS安装与使用教程

QGIS安装与使用教程

weixin_46713695的博客 2万+

java aop日志保存_Spring Boot AOP记录用户操作日志

在Spring框架中,使用AOP配合自定义注解可以方便的实现用户操作的监控。首先搭建一个基本的Spring Boot Web环境开启Spring Boot,然后引入必要依赖:org.springframework.bootspring-boot-starter-jdbcorg.springframework.bootspring-boot-starter-aopcom.oracleojdbc66....

weixin_36327582的博客 373

【用unity实现100个游戏之1】制作类元气骑士、挺进地牢——俯视角射击游戏多种射击效果(二)(附源码)

这篇文章我们将继续实现曲线射击与两种不需要实体子弹的射击方式 源码在文章末尾。

向宇的博客,专注php/web全栈 unity游戏开发,欢迎大家评论纠错 5061

tp5记录用户的操作日志_Spring Boot AOP记录用户操作日志

点击上方☝SpringForAll社区轻松关注!及时获取有趣有料的技术文章来源:https://mrbird.cc/Spring-Boot-AOP%20log.html在Spring框架中,使用AOP配合自定义注解可以方便的实现用户操作的监控。首先搭建一个基本的Spring Boot Web环境开启Spring Boot,然后引入必要依赖: 1<dependency> 2...

weixin_39690401的博客 504

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Spring Boot + Aop 记录用户操作日志

本文主要介绍通过AOP记录用户操作日志,这也是目前比较常用的用法,由于水平有限,所以可能存在错漏之处,望指正。

xmg_zs的博客 6966

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

tp5记录用户的操作日志_Spring boot学习,Spring boot实现AOP记录操作日志

前言在实际的项目中,特别是管理系统中,对于那些重要的操作我们通常都会记录操作日志。比如对数据库的CRUD操作,我们都会对每一次重要的操作进行记录,通常的做法是向数据库指定的日志表中插入一条记录。这里就产生了一个问题,难道要我们每次在 CRUD的时候都手动的插入日志记录吗?这肯定是不合适的,这样的操作无疑是加大了开发量,而且不易维护,所以实际项目中总是利用AOP(Aspect Oriented Pr...

weixin_39831104的博客 272

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

基于Spring Boot 整合AOP记录用户操作日志

背景:使用AOP面向切面记录用户进入系统后的操作轨迹。 其他:SpringBoot + MybatisPlus + … 相关依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</arti...

LionHerding的博客 498

Spring Boot 使用AOP切面编程记录用户操作日志

Spring Boot AOP记录用户操作日志1、pom.xml导入依赖2、实体类(com.stodgy.bean)3、SystemLogDao Dao层(com.stodgy.dao)4、新建对应dao层的mapper.xml文件5、Service (com.stodgy.service)6、ServiceImpl (com.stodgy.service.impl)前面这些基本只是一些准备工作,下面步入主题7、Log (com.stodgy.annotation)8、工具类 IPUtils 和 HttpC

Styodg_白的博客 569
上一篇: 无套路,3分钟带你轻松上手SonarQube - 代码质量检测平台
下一篇: Java阻塞队列的简单实现
SpringForAll
博客等级 码龄7年 15粉丝 79原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值