首页 > 其他分享 >SpringBoot + 自定义注解,实现用户操作日志(支持SpEL表达式)

SpringBoot + 自定义注解,实现用户操作日志(支持SpEL表达式)

时间:2023-09-11 09:11:24浏览次数:50  
标签:userName dto SpringBoot 自定义 userId 用户 接口 SpEL 日志

背景

一个成熟的系统,都会针对一些关键的操作,去创建用户操作日志。

比如:

XX人创建了一条订单,订单号:XXXXXXXXX

因为操作人或者订单号是动态的,所以有些开发人员,不知道获取,就将这种操作日志和业务代码融在一起。

我们当然要杜绝这种现象,一定会有更好的解决方案。

当前项目除了满足上面这个基础需求场景外,还可以满足一些常见的日志记录需求。

下面通过一些测试用例来了解下当前项目吧。

一、支持SpEL表达式

1、使用场景

我们在记录操作日志的时候,为了获取接口中的入参信息,就可以通过SpEL表达式。

2、接口示例

 @GetMapping(value = "/queryUser")
 @OperateLog(bizNo = "{#userName}", operateName = "查询用户", operateContent = "通过 {#userName} 查询用户")
 public Result<String> queryUser(@RequestParam String userName) {
        return Result.success(userName);
}

这里入参 userName 的获取,就是通过SpEL表达式获取到

3、请求接口

http://localhost:8080/queryUser?userName=James

4、输出日志

日志操作记录------ OperateLogDTO(operator=张三, bizNo=James, operateName=查询用户, operateContent=通过 James 查询用户, status=true, errMsg=null)

可以看出通过SpEL表达式,已经将 {#userName} 占位符,成功替换请求的参数 James


二、支持函数表达式

1、使用场景

有些时候我们仅仅是获取请求参数的数据还不够,还需要拿着请求参数的数据,去请求其它接口,才能组成一条完整的日志,最典型的场景就是

商品ID为 XXX 的商品的名称已经从 XXX  改成 XXX

这里前端肯定只会传当前的商品ID和当前修改后的商品名称,也就是说该商品老的名称还需要通过商品ID去商品表查完后,才能组成完整日志。

2、接口示例

@GetMapping(value = "/deleteUser")
@OperateLog(bizNo = "{#userId}", operateName = "删除用户",
        operateContent = "用户id为 {#userId} 用户名为 [getUserNameByUserId{#userId}] 已被删除")
public Result<Void> deleteUser(Long userId) {
        return Result.success();
        }

3、请求接口

http://localhost:8080/deleteUser?userId=888

4、输出日志

日志操作记录------ OperateLogDTO(operator=张三, bizNo=888, operateName=删除用户, operateContent=用户id为 888 用户名为 张老三 已被删除, status=true, errMsg=null)

这里用户名张老三,是模拟查询数据库获取的用户名。


三、支持三目表达式

1、使用场景

有时候我们可能根据是否传主键id来判断是新增还是更新,或者传不同的type来确定什么操作类型。

2、接口示例

@PostMapping(value = "/saveOrUpdateUser")
@OperateLog(bizNo = "{#dto.userId}", operateName = "#dto.userId == null ? '新增用户':'更新用户'",
        operateContent = "#dto.userId == null ? '新增' + #dto.userName + '用户':'将用户id为' + #dto.userId + '的用户名更新为' + #dto.userName")
public Result<Void> saveOrUpdateUser(@RequestBody UserDTO dto) {
        return Result.success();
}

3、请求示例

请求url

localhost:8080/saveOrUpdateUser

请求参数

{
  "userId": 17,
  "userName": "赵磊"
}

4、输出日志

传入userId的日志

日志操作记录------ OperateLogDTO(operator=张三, bizNo=null, operateName=更新用户, operateContent=将用户id为17的用户名更新为赵磊, status=true, errMsg=null)

如果不传入userId只传userName,我们再看下日志

日志操作记录------ OperateLogDTO(operator=张三, bizNo=null, operateName=新增用户, operateContent=新增赵磊用户, status=true, errMsg=null)

四、支持标记成功日志或业务异常日志

1、使用场景

请求一个接口的时候,可以分为三种情况:

  • 接口返回成功,同时返回成功状态码
  • 接口返回成功,但返回业务异常状态码,比如:没有查询到该订单信息
  • 接口直接报错,比如我们常见的空指针异常

对于第三种情况,我们可以不去记录这个用户操作日志,如果有需要可以记录在异常记录表中。

但对于第一和第二种情况,我们需要记录操作是成功还是失败。

2、接口示例

@PostMapping(value = "/saveUser")
@OperateLog(bizNo = "{#dto.userId}", operateName = "新增用户", operateContent = "新增用户名为{#dto.userName}")
public Result<Void> saveUser(@RequestBody UserDTO dto) {
        return Result.failed("该用户名称已存在");
        }

可以看出接口返回的是 该用户名称已存在,业务异常。

3、请求示例

请求url

localhost:8080/saveUser

请求参数

{
  "userId": 2,
  "userName": "阎平"
}

4、输出日志

日志操作记录------ OperateLogDTO(operator=张三, bizNo=2, operateName=新增用户, operateContent=新增用户名为阎平, status=false, errMsg=该用户名称已存在)

可以看出这里的status状态是 false,同时记录了错误原因 该用户名称已存在

最后附上GitHub源码地址:

https://github.com/yudiandemingzi/spring-boot-operate-log



声明: 公众号如需转载该篇文章,发表文章的头部一定要 告知是转至公众号: 后端元宇宙。同时也可以问本人要markdown原稿和原图片。其它情况一律禁止转载!

标签:userName,dto,SpringBoot,自定义,userId,用户,接口,SpEL,日志
From: https://www.cnblogs.com/qdhxhz/p/17684311.html

相关文章

  • SpringBoot创建Thymeleaf
    1.pom.xml导入依赖<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency> 2.thymelef的默认配置文件springboot工程默认有一个templates文件夹,所有的html页面都放这个文件夹里。......
  • MySQL数据库进阶 自定义函数
    自定义函数在MySQL中,您可以使用自定义函数来扩展数据库管理系统的功能。自定义函数允许您封装一段可重用的代码,并在查询和其他操作中调用它。以下是在MySQL中创建和使用自定义函数的一般步骤:1、创建自定义函数语法:CREATEFUNCTIONfunction_name(parameters)RETURNSreturn_t......
  • SpringBoot 如何实现文件上传和下载
    当今Web应用程序通常需要支持文件上传和下载功能,SpringBoot提供了简单且易于使用的方式来实现这些功能。在本篇文章中,我们将介绍SpringBoot如何实现文件上传和下载,同时提供相应的代码示例。 文件上传SpringBoot提供了Multipart文件上传的支持。Multipart是HTTP协议中的一种......
  • 实现读写分离SpringBoot+MyBatis+Druid
    实现读写分离SpringBoot+MyBatis+Druid1.读写分离概念理解读写分离要做的事情就是对于一条SQL该选择哪个数据库去执行,至于谁来做选择数据库这件事儿,无非两个,要么中间件帮我们做,要么程序自己做。因此,一般来讲,读写分离有两种实现方式。第一种是依靠中间件(比如:MyCat),也就是说应用程......
  • 在springboot项目种引入element组件
    1、保证vue的版本在3以上2、Win+R--打开命令行窗口(cmd)输入下面的命令,打开图形化界面:vueui3、打开我们创建的vue项目选择路径即可自主导入项目;4、安装element-ui的插件依赖5、查看项目中是否存在ok!......
  • 基于SpringBoot的高校党员信息管理系统的设计与实现-计算机毕业设计源码+LW文档
    摘要:中国的高校线上党建在国内有着非常好的使用前景,所以决定开发基于SpringBoot的高校党员信息管理系统。本系统能够满足党员的日常学习的需要,以及适应现代化党员管理的需求。本系统开发设计思想是实现在线管理的数字化。达到帮助高校进行网上管理,使党员管理工作更加高效的目的。......
  • SpringBoot基本知识
    SpringBoot基本知识一、简介1、springBoot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。通过这种方式,SpringBoot致力于在蓬勃发展的快速应用开发领域(ra......
  • Springboot项目中pom.xml配置文件无法解析下载oracl数据库解决办法(Cannot resolve com
    网上说是因Oracle的版权问题,导致maven下载不下来ojdbc各个版本的jar包。就会报错Cannotresolvecom.oracle:ojdbc6:11.2.0.1.0 经过一番百度,找到了一个适用的解决方法,如下操作即可:1.在终端或客户端机器上找到oracle安装驱动目录:例如:E:\myorcl\product\11.2.0\dbhome_1\j......
  • Springboot集成OceanBase4.x
    概述    在Springboot项目中使用Oceanbase4.2版本数据库。pomPS:可在maven仓库中搜索oceanbase,第一个就是。<dependency> <groupId>com.oceanbase</groupId> <artifactId>oceanbase-client</artifactId> <version>2.4.4</version></dependency>......
  • 记一次SpringBoot Filter的过滤器被重复执行问题
    记一次SpringBootFilter的过滤器被重复执行问题debug发现过滤器执行两次,后来定位到WebFilter和Component注解导致多次扫描,而这次需要用到WebFilter,所以注掉了Component@Order(0)//@Component@WebFilter(urlPatterns={"/*"})@ConditionalOnProperty(name="color.trace.s......