前言:
任何一个项目都会有一个用户操作日志(也叫行为日志)的模块,它主要用来记录某个用户做了某个操作,当出现操作失败时,通过日志就可以快速的查找是哪个用户在哪个模块出现了错误,以便于开发人员快速定位问题所在。

实现这一功能一般有两种方法:

  • 第一种就是很传统的做法,就是在每个模块进行插入日志的操作(不推荐),这种做法虽然实现了记录用户的操作,但很繁琐而且基本上是重复的工作。
  • 第二种就是使用Spring的AOP来实现记录用户操作,也是推荐的现如今都使用的一种做法。它的优势在于这种记录用户操作的代码独立于其他业务逻辑代码,不仅实现了解耦,而且避免了冗余代码。

具体实现步骤

  1. 在pom.xml中添加AOP依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency>`

  1. 设计操作日志记录表
  1. 新增日志实体类、dao层 接口
  2. 自定义操作日志记录的注解
package com.example.springcloud.aop;import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** @author lyz* @title: OperationLog* @projectName springcloud* @date 2020/9/23* @description: 自定义操作日志注解*/
@Target(ElementType.METHOD)//注解放置的目标位置即方法级别
@Retention(RetentionPolicy.RUNTIME)//注解在哪个阶段执行
@Documented
public @interface OperationLogAnnotation {String operModul() default ""; // 操作模块String operType() default "";  // 操作类型String operDesc() default "";  // 操作说明
}

  1. 自定义操作日志切面类,该类是将操作日志保存到数据库
package com.example.springcloud.aop;import com.example.springcloud.dao.OperationLogDao;
import com.example.springcloud.domain.OperationLog;
import com.example.springcloud.utils.IPUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;/*** @author lyz* @title: OperationAspect* @projectName springcloud* @date 2020/9/23* @description: 操作日志切面处理类*/
@Aspect
@Component
public class OperationLogAspect {@AutowiredOperationLogDao logDao;private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");/*** 设置操作日志切入点   在注解的位置切入代码*/@Pointcut("@annotation(com.example.springcloud.aop.OperationLogAnnotation)")public void operLogPoinCut() {}@AfterReturning(returning  /*** 记录操作日志* @param joinPoint 方法的执行点* @param result  方法返回值* @throws Throwable*/ = "result", value = "operLogPoinCut()")public void saveOperLog(JoinPoint joinPoint, Object result) throws Throwable {// 获取RequestAttributesRequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();// 从获取RequestAttributes中获取HttpServletRequest的信息HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);try {//将返回值转换成map集合Map<String, String> map = (Map<String, String>) result;OperationLog operationLog = new OperationLog();// 从切面织入点处通过反射机制获取织入点处的方法MethodSignature signature = (MethodSignature) joinPoint.getSignature();//获取切入点所在的方法Method method = signature.getMethod();//获取操作OperationLogAnnotation annotation = method.getAnnotation(OperationLogAnnotation.class);if (annotation != null) {operationLog.setModel(annotation.operModul());operationLog.setType(annotation.operType());operationLog.setDescription(annotation.operDesc());}//操作时间operationLog.setOperationTime(Timestamp.valueOf(sdf.format(new Date())));//操作用户operationLog.setUserCode(request.getHeader("userCode"));//操作IPoperationLog.setIp(IPUtil.getIpAdrress(request));//返回值信息operationLog.setResult(map.get("message"));//保存日志logDao.save(operationLog);} catch (Exception e) {e.printStackTrace();}}}

  1. 在controller层的某一个方法加入@OperationLogAnnotation 注解
package com.example.springcloud.controller;import com.example.springcloud.aop.OperationLogAnnotation;
import com.example.springcloud.domain.User;
import com.example.springcloud.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpRequest;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest;
import java.util.Map;/*** @author lyz* @title: UserController* @projectName springcloud* @date 2020/9/12* @description:*/
@Api(tags = "用户表")
@RestController
@RequestMapping("/user")
public class UserController {@AutowiredUserService userService;@OperationLogAnnotation(operModul = "用户模块-用户列表",operType = "查询",operDesc = "查询所有用户")@ApiOperation(value = "查询所有用户",notes = "这是用来查询所有用户列表")@GetMapping("/users")public Object findAll(@RequestParam(required = false)String userName,@RequestParam(required = false)Integer sex,@RequestParam(required = false, defaultValue = "10") int limit,@RequestParam(required = false, defaultValue = "0") int offset,@RequestParam(required = false, defaultValue = "createTime") String sortBy,@RequestParam(required = false, defaultValue = "DESC") String sortFlag, HttpServletRequest request){offset=offset/limit;request.setAttribute("userCode","admin");return userService.findAll(userName,sex,sortBy,sortFlag,offset,limit);}@OperationLogAnnotation(operModul = "用户模块-新增用户",operType = "新增",operDesc = "新增用户")@PostMapping("/addUser")@ApiOperation(value = "新增用户",notes = "通过这个方法可以添加新用户")public Object createUser(@RequestBody Map<String, String>map){return userService.save(map);}}

  1. 通过swagger或者postmain进行测试,最后在数据库中查看操作日志记录

总结:用户操作日志是AOP最常见的一种业务场景,这里使用了后置通知,当然也可以也可以使用异常通知记录异常信息,方法如上。

原文作者:哥的冷酷,你模仿不来

原文链接:https://segmentfault.com/a/1190000023961648

原文出处:CSDN

中操作日志文件记录的是什么_SpringBoot+AOP实现用户操作日志的记录相关推荐

  1. linux用户在哪个文件夹,LINUX中用命令成功建立一个用户后信息会记录在哪个文件中...

    LINUX中用命令成功建立一个用户后信息会记录在哪个文件中 发布时间:2007-07-28 10:14:57来源:红联作者:MPiops 增加用户帐号后 新建用户的命令十分简单,在命令行下使用 use ...

  2. word中出现“由于文件许可权错误,word无法完成保存操作”的解决办法

    前几天重装了一个系统,系统自带了word2003,在使用word2003时碰到过这种情况:保存时,弹出对话框提示"由于文件许可权错误,Word无法完成保存操作",接下来提示需要保 ...

  3. mysql 日志文件 自动_教你自动恢复MySQL数据库的日志文件

    如果MySQL服务器启用了二进制日志,你可以使用mysqlbinlog工具来恢复从指定的时间点开始 (例如,从你最后一次备份)直到现在或另一个指定的时间点的数据."mysqlbinlog:用 ...

  4. 服务器日志文件可以删吗,C:\Windows\Logs\CBS 里面的日志文件能否删除?

    问题C:\Windows\Logs\CBS 里面的日志文件能否删除? C:\Windows\Logs\CBS 里面log文件有8个G了,而我现在C盘剩余空间为16MB , 请问这里面的日志能否删除,有 ...

  5. php怎么把日志推送过去_实践 | 基于Flink的用户行为日志分析系统

    用户行为日志分析是实时数据处理很常见的一个应用场景,比如常见的PV.UV统计.本文将基于Flink从0到1构建一个用户行为日志分析系统,包括架构设计与代码实现.本文分享将完整呈现日志分析系统的数据处理 ...

  6. 腾讯通服务器查看消息记录,rtx怎么在服务端查看用户登录日志

    腾讯通RTX如何与QQ好友通信(1)     实现与外部QQ好友通信的前提,是RTX服务端申请了企业外部号码(即特殊号段QQ号码),并将号码分配给了客户端RTX用户    一.在RTX上添加QQ好友 ...

  7. linux中如何将文件夹权限由root改为user用户

    比如当前文件夹权限为root,我希望改为acptuser权限: #将/home/acptuser/services-war权限改为acptuser: chown -R acptuser:acptuse ...

  8. linux审计日志清除,Linux登录安全及用户操作审计 ,linux下清理日志脚本

    一.合理使用Shell历史命令记录功能 Linux下可通过history命令查看用户所有历史操作记录,同时shell命令操作记录默认保存在用户目录下的.bash_history文件中,有时候***会删 ...

  9. slf4j没有在linux中生成日志,slf4j日志记录问题 - 未生成日志文件

    我正在使用slf4j通过java实用程序日志记录.我试图放置logging.properties文件,以便它会被我的web应用程序拾取.以下是我的logging.properties文件怎么样子:sl ...

最新文章

  1. Matplotlib可视化散点图、配置X轴为对数坐标、并使用线条(line)连接散点图中的数据点(Simple Line Plot with Data points in Matplotlib)
  2. 回文子串—leetcode647
  3. vue_组件_监听组件事件
  4. mysql支持的平台和操作系统_MySQL 数据库所支持的操作系统_MySQL
  5. LeetCode 88. Merge Sorted Array
  6. java 枚举 大小_Java枚举入门
  7. 微服务在微信的架构实践
  8. 1065. 最小公倍数
  9. 单片机c语言常用的语句有几条,单片机C语言教程-基础语句
  10. idea远程调试修改代码_利用IDEA远程调试代码
  11. 环洋市场咨询:全球OLED收入预计2028年达到502.4亿美元
  12. 太帅了!钟楚曦这件老爹裤A到炸裂,一般人可穿不出这种范
  13. 讯飞智能录音笔SR502:支持OCR识别功能的职场礼物
  14. Nature综述:微生物构成的氮循环网络(必读)
  15. 微软内部封杀 Slack
  16. 教你如何制作浪漫的表白网站
  17. flink yarn模式提交及查看日志
  18. Hibernate5自动建表坑之索引BUG(Cant DROP xxxxxxxxx check that column/key exists)
  19. 分布式、集群概念汇总(二)
  20. html5手指测速,网速html5网速测试进度条代码

热门文章

  1. memset函数及其用法,C语言memset函数详解
  2. MLCC噪声啸叫及对策
  3. 【转】贴片电阻的工作寿命
  4. C++利用构造函数限制对象的创建
  5. JavaScript发布订阅者模式
  6. 烂泥:高负载均衡学习haproxy之关键词介绍
  7. javax.net.ssl.SSLHandshakeException(Cas导入证书)
  8. 项目常用工具类整理(五)--jar包整理
  9. Thrift Java Servers Compared
  10. Ubuntu下Git服务端搭建