点击上方蓝色“方志朋”,选择“设为星标”

回复“666”获取独家整理的学习资料!

作者:咫尺的梦想_w

cnblogs.com/wm-dv/p/11735828.html

平时我们在做项目时经常需要对一些重要功能操作记录日志,方便以后跟踪是谁在操作此功能;我们在操作某些功能时也有可能会发生异常,但是每次发生异常要定位原因我们都要到服务器去查询日志才能找到,而且也不能对发生的异常进行统计,从而改进我们的项目,要是能做个功能专门来记录操作日志和异常日志那就好了。

当然我们肯定有方法来做这件事情,而且也不会很难,我们可以在需要的方法中增加记录日志的代码,和在每个方法中增加记录异常的代码,最终把记录的日志存到数据库中。听起来好像很容易,但是我们做起来会发现,做这项工作很繁琐,而且都是在做一些重复性工作,还增加大量冗余代码,这种方式记录日志肯定是不可行的。

我们以前学过Spring 三大特性,IOC(控制反转),DI(依赖注入),AOP(面向切面),那其中AOP的主要功能就是将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来。今天我们就来用springBoot Aop 来做日志记录,好了,废话说了一大堆还是上货吧。

一、创建日志记录表、异常日志表,表结构如下:

操作日志表

异常日志表

二、添加Maven依赖

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

三、创建操作日志注解类OperLog.java

package com.hyd.zcar.cms.common.utils.annotation;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 wu*/
@Target(ElementType.METHOD) //注解放置的目标位置,METHOD是可注解在方法级别上
@Retention(RetentionPolicy.RUNTIME) //注解在哪个阶段执行
@Documented
public @interface OperLog {String operModul() default ""; // 操作模块String operType() default "";  // 操作类型String operDesc() default "";  // 操作说明
}

四、创建切面类记录操作日志

package com.hyd.zcar.cms.common.utils.aop;import java.lang.reflect.Method;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;import javax.servlet.http.HttpServletRequest;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.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;import com.gexin.fastjson.JSON;
import com.hyd.zcar.cms.common.utils.IPUtil;
import com.hyd.zcar.cms.common.utils.annotation.OperLog;
import com.hyd.zcar.cms.common.utils.base.UuidUtil;
import com.hyd.zcar.cms.common.utils.security.UserShiroUtil;
import com.hyd.zcar.cms.entity.system.log.ExceptionLog;
import com.hyd.zcar.cms.entity.system.log.OperationLog;
import com.hyd.zcar.cms.service.system.log.ExceptionLogService;
import com.hyd.zcar.cms.service.system.log.OperationLogService;/*** 切面处理类,操作日志异常日志记录处理** @author wu* @date 2019/03/21*/
@Aspect
@Component
public class OperLogAspect {/*** 操作版本号* <p>* 项目启动时从命令行传入,例如:java -jar xxx.war --version=201902* </p>*/@Value("${version}")private String operVer;@Autowiredprivate OperationLogService operationLogService;@Autowiredprivate ExceptionLogService exceptionLogService;/*** 设置操作日志切入点 记录操作日志 在注解的位置切入代码*/@Pointcut("@annotation(com.hyd.zcar.cms.common.utils.annotation.OperLog)")public void operLogPoinCut() {}/*** 设置操作异常切入点记录异常日志 扫描所有controller包下操作*/@Pointcut("execution(* com.hyd.zcar.cms.controller..*.*(..))")public void operExceptionLogPoinCut() {}/*** 正常返回通知,拦截用户操作日志,连接点正常执行完成后执行, 如果连接点抛出异常,则不会执行** @param joinPoint 切入点* @param keys      返回结果*/@AfterReturning(value = "operLogPoinCut()", returning = "keys")public void saveOperLog(JoinPoint joinPoint, Object keys) {// 获取RequestAttributesRequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();// 从获取RequestAttributes中获取HttpServletRequest的信息HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);OperationLog operlog = new OperationLog();try {operlog.setOperId(UuidUtil.get32UUID()); // 主键ID// 从切面织入点处通过反射机制获取织入点处的方法MethodSignature signature = (MethodSignature) joinPoint.getSignature();// 获取切入点所在的方法Method method = signature.getMethod();// 获取操作OperLog opLog = method.getAnnotation(OperLog.class);if (opLog != null) {String operModul = opLog.operModul();String operType = opLog.operType();String operDesc = opLog.operDesc();operlog.setOperModul(operModul); // 操作模块operlog.setOperType(operType); // 操作类型operlog.setOperDesc(operDesc); // 操作描述}// 获取请求的类名String className = joinPoint.getTarget().getClass().getName();// 获取请求的方法名String methodName = method.getName();methodName = className + "." + methodName;operlog.setOperMethod(methodName); // 请求方法// 请求的参数Map<String, String> rtnMap = converMap(request.getParameterMap());// 将参数所在的数组转换成jsonString params = JSON.toJSONString(rtnMap);operlog.setOperRequParam(params); // 请求参数operlog.setOperRespParam(JSON.toJSONString(keys)); // 返回结果operlog.setOperUserId(UserShiroUtil.getCurrentUserLoginName()); // 请求用户IDoperlog.setOperUserName(UserShiroUtil.getCurrentUserName()); // 请求用户名称operlog.setOperIp(IPUtil.getRemortIP(request)); // 请求IPoperlog.setOperUri(request.getRequestURI()); // 请求URIoperlog.setOperCreateTime(new Date()); // 创建时间operlog.setOperVer(operVer); // 操作版本operationLogService.insert(operlog);} catch (Exception e) {e.printStackTrace();}}/*** 异常返回通知,用于拦截异常日志信息 连接点抛出异常后执行** @param joinPoint 切入点* @param e         异常信息*/@AfterThrowing(pointcut = "operExceptionLogPoinCut()", throwing = "e")public void saveExceptionLog(JoinPoint joinPoint, Throwable e) {// 获取RequestAttributesRequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();// 从获取RequestAttributes中获取HttpServletRequest的信息HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);ExceptionLog excepLog = new ExceptionLog();try {// 从切面织入点处通过反射机制获取织入点处的方法MethodSignature signature = (MethodSignature) joinPoint.getSignature();// 获取切入点所在的方法Method method = signature.getMethod();excepLog.setExcId(UuidUtil.get32UUID());// 获取请求的类名String className = joinPoint.getTarget().getClass().getName();// 获取请求的方法名String methodName = method.getName();methodName = className + "." + methodName;// 请求的参数Map<String, String> rtnMap = converMap(request.getParameterMap());// 将参数所在的数组转换成jsonString params = JSON.toJSONString(rtnMap);excepLog.setExcRequParam(params); // 请求参数excepLog.setOperMethod(methodName); // 请求方法名excepLog.setExcName(e.getClass().getName()); // 异常名称excepLog.setExcMessage(stackTraceToString(e.getClass().getName(), e.getMessage(), e.getStackTrace())); // 异常信息excepLog.setOperUserId(UserShiroUtil.getCurrentUserLoginName()); // 操作员IDexcepLog.setOperUserName(UserShiroUtil.getCurrentUserName()); // 操作员名称excepLog.setOperUri(request.getRequestURI()); // 操作URIexcepLog.setOperIp(IPUtil.getRemortIP(request)); // 操作员IPexcepLog.setOperVer(operVer); // 操作版本号excepLog.setOperCreateTime(new Date()); // 发生异常时间exceptionLogService.insert(excepLog);} catch (Exception e2) {e2.printStackTrace();}}/*** 转换request 请求参数** @param paramMap request获取的参数数组*/public Map<String, String> converMap(Map<String, String[]> paramMap) {Map<String, String> rtnMap = new HashMap<String, String>();for (String key : paramMap.keySet()) {rtnMap.put(key, paramMap.get(key)[0]);}return rtnMap;}/*** 转换异常信息为字符串** @param exceptionName    异常名称* @param exceptionMessage 异常信息* @param elements         堆栈信息*/public String stackTraceToString(String exceptionName, String exceptionMessage, StackTraceElement[] elements) {StringBuffer strbuff = new StringBuffer();for (StackTraceElement stet : elements) {strbuff.append(stet + "\n");}String message = exceptionName + ":" + exceptionMessage + "\n\t" + strbuff.toString();return message;}
}

五、在Controller层方法添加@OperLog注解

六、操作日志、异常日志查询功能

热门内容:
  • 今天终于搞懂了:为什么 Java 的 main 方法必须是 public static void?

  • 七个开源的 SpringBoot 前后端分离项目,Star过千,快去收藏夹吃灰吧!

  • 道友自诉:入职中软一个月(外包华为)就离职了!

  • 腾讯推出高性能 RPC 开发框架

最近面试BAT,整理一份面试资料《Java面试BAT通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。
明天见(。・ω・。)

如何使用SpringBoot AOP 记录操作日志、异常日志?相关推荐

  1. SpringBoot AOP 记录操作日志、异常日志

    使用SpringBoot AOP 记录操作日志.异常日志 我们在做项目时经常需要对一些重要功能操作记录日志,方便以后跟踪是谁在操作此功能.在操作某些功能时也有可能会发生异常,但是每次发生异常要定位原因 ...

  2. 使用SpringBoot AOP 记录操作日志、异常日志

    https://www.cnblogs.com/wm-dv/p/11735828.html

  3. springboot aop + logback + 统一异常处理 打印日志

    springboot aop + logback + 统一异常处理 打印日志 参考文章: (1)springboot aop + logback + 统一异常处理 打印日志 (2)https://ww ...

  4. 用aspect在springboot中记录操作日志至数据库的详细过程

    代码来自若依管理系统的后台,我截取的其中用于记录操作日志的部分 1.切面 2.操作日志表 3.spring工具类 4.客户端工具类 异步工厂(产生任务用) 异步任务管理器 5.服务层 6.控制层 1. ...

  5. Spring AOP 实现业务和异常日志记录实战

    1 业务需求:今日,公司要求对操作的业务和日志统一做处理,需要把业务表数据相关信息存入日志表中,比如表名,方法名,业务id,操作操作时间modifyTIme等等. 除了在业务主动插入日志数据之外,有个 ...

  6. Spring aop 记录操作日志 Aspect 自定义注解

    时间过的真快,转眼就一年了,没想到随手写的笔记会被这么多人浏览,不想误人子弟,于是整理了一个优化版,在这里感谢智斌哥提供的建议和帮助,话不多说,进入正题 所需jar包 :spring4.3相关联以及a ...

  7. SpringBoot AOP 记录WEB请求日志

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/catoop/article/details/71556374 接上一篇文章: http://blog ...

  8. java通用日志记录_JAVA实现通用日志记录方法

    前言: 之前想在filter层直接过滤httpServerletRequest请求进行日志处理,但是之后再getWriter()的 时候报already been call异常.查了下,才发现原来流形 ...

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

    目录 一.前言 二.实战 1.设计用户操作日志表: sys_oper_log 2.引入依赖 3.自定义用户操作日志注解 4.自定义用户操作日志切面 5.MyLog注解的使用 6.最终效果 三.总结 一 ...

最新文章

  1. 【MIT Sam Hopkins教授】如何读论文?How to Read a Paper
  2. 如何设置mysql让其他人能访问_怎么配置MySQL数据库让别人远程访问
  3. Dataset之Knifey-Spoony:Knifey-Spoony数据集的简介、下载、使用方法之详细攻略
  4. 定义一个数组返回最大子数组的值(1)
  5. replace into mysql去重_上传 phpexcel 类 入库并入库前去重
  6. EditPlus3.21注册码
  7. create-react-app应用的入口定义
  8. [vue插件]基于vue2.x的电商图片放大镜插件
  9. 华为调研了82位离职博士,任正非发电邮深讨人才流失根源
  10. 同质异质网络——(F(fraud) A(Analytics) UDPSNT(Wylie_2015))
  11. json-smart 使用示例(推荐fastjson)
  12. Kubernetes 持续集成 SpringCloud
  13. matlab为数据加表头,matlab xlswrite 表头
  14. tp6中kafka使用
  15. arduino 鸿蒙,arduino入门开发案例(上)
  16. 被称为史上最高效学习方法——费曼学习法
  17. Oracle12C 基本操作和使用
  18. 电阻(5)NTC电阻篇
  19. python提示IndentationError: unexpected indent错误
  20. 别踩白块_前端H5游戏毕设

热门文章

  1. 二叉树的镜像(数组,前后 遍历重建二叉树)
  2. 基于WebSocket实现聊天室(Node)
  3. 虚函数表剖析,网上转的,呵呵
  4. Windows 7 SDK Fails to Install with Return Code 5100 (GRMSDK_EN_DVD.iso)
  5. Multithread 之 introduction
  6. C++_volatile限定修饰符 Pair类型
  7. LeetCode刷题宝典 V1.0 PDF下载
  8. 刻意练习:LeetCode实战 -- Task13. 罗马数字转整数
  9. 【机器学习】基于粒子群算法的非线性函数寻优
  10. 《C#精彩实例教程》小组阅读12 -- C#面向对象技术高级应用