<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          使用SpringBoot AOP 記錄操作日志、異常日志

          共 8674字,需瀏覽 18分鐘

           ·

          2020-10-09 21:09

          注意文末有最新Java實戰(zhàn)項目面試題


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


          平時我們在做項目時經(jīng)常需要對一些重要功能操作記錄日志,方便以后跟蹤是誰在操作此功能;我們在操作某些功能時也有可能會發(fā)生異常,但是每次發(fā)生異常要定位原因我們都要到服務(wù)器去查詢?nèi)罩静拍苷业剑乙膊荒軐Πl(fā)生的異常進行統(tǒng)計,從而改進我們的項目,要是能做個功能專門來記錄操作日志和異常日志那就好了。

          當然我們肯定有方法來做這件事情,而且也不會很難,我們可以在需要的方法中增加記錄日志的代碼,和在每個方法中增加記錄異常的代碼,最終把記錄的日志存到數(shù)據(jù)庫中。聽起來好像很容易,但是我們做起來會發(fā)現(xiàn),做這項工作很繁瑣,而且都是在做一些重復性工作,還增加大量冗余代碼,這種方式記錄日志肯定是不可行的。

          我們以前學過Spring 三大特性,IOC(控制反轉(zhuǎn)),DI(依賴注入),AOP(面向切面),那其中AOP的主要功能就是將日志記錄,性能統(tǒng)計,安全控制,事務(wù)處理,異常處理等代碼從業(yè)務(wù)邏輯代碼中劃分出來。今天我們就來用springBoot Aop 來做日志記錄,好了,廢話說了一大堆還是上貨吧。

          一、創(chuàng)建日志記錄表、異常日志表,表結(jié)構(gòu)如下:

          操作日志表

          異常日志表

          二、添加Maven依賴


          ????org.springframework.boot
          ????spring-boot-starter-aop

          三、創(chuàng)建操作日志注解類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)?//注解在哪個階段執(zhí)行
          @Documented
          public?@interface?OperLog?{
          ????String?operModul()?default?"";?//?操作模塊
          ????String?operType()?default?"";??//?操作類型
          ????String?operDesc()?default?"";??//?操作說明
          }

          四、創(chuàng)建切面類記錄操作日志

          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?{

          ????/**
          ?????*?操作版本號
          ?????*?


          ?????*?項目啟動時從命令行傳入,例如:java -jar xxx.war --version=201902
          ?????*?


          ?????*/

          ????@Value("${version}")
          ????private?String?operVer;

          ????@Autowired
          ????private?OperationLogService?operationLogService;

          ????@Autowired
          ????private?ExceptionLogService?exceptionLogService;

          ????/**
          ?????*?設(shè)置操作日志切入點?記錄操作日志?在注解的位置切入代碼
          ?????*/

          ????@Pointcut("@annotation(com.hyd.zcar.cms.common.utils.annotation.OperLog)")
          ????public?void?operLogPoinCut()?{
          ????}

          ????/**
          ?????*?設(shè)置操作異常切入點記錄異常日志?掃描所有controller包下操作
          ?????*/

          ????@Pointcut("execution(*?com.hyd.zcar.cms.controller..*.*(..))")
          ????public?void?operExceptionLogPoinCut()?{
          ????}

          ????/**
          ?????*?正常返回通知,攔截用戶操作日志,連接點正常執(zhí)行完成后執(zhí)行,?如果連接點拋出異常,則不會執(zhí)行
          ?????*
          ?????*?@param?joinPoint?切入點
          ?????*?@param?keys??????返回結(jié)果
          ?????*/

          ????@AfterReturning(value?=?"operLogPoinCut()",?returning?=?"keys")
          ????public?void?saveOperLog(JoinPoint?joinPoint,?Object?keys)?{
          ????????//?獲取RequestAttributes
          ????????RequestAttributes?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);?//?請求方法

          ????????????//?請求的參數(shù)
          ????????????Map?rtnMap?=?converMap(request.getParameterMap());
          ????????????//?將參數(shù)所在的數(shù)組轉(zhuǎn)換成json
          ????????????String?params?=?JSON.toJSONString(rtnMap);

          ????????????operlog.setOperRequParam(params);?//?請求參數(shù)
          ????????????operlog.setOperRespParam(JSON.toJSONString(keys));?//?返回結(jié)果
          ????????????operlog.setOperUserId(UserShiroUtil.getCurrentUserLoginName());?//?請求用戶ID
          ????????????operlog.setOperUserName(UserShiroUtil.getCurrentUserName());?//?請求用戶名稱
          ????????????operlog.setOperIp(IPUtil.getRemortIP(request));?//?請求IP
          ????????????operlog.setOperUri(request.getRequestURI());?//?請求URI
          ????????????operlog.setOperCreateTime(new?Date());?//?創(chuàng)建時間
          ????????????operlog.setOperVer(operVer);?//?操作版本
          ????????????operationLogService.insert(operlog);
          ????????}?catch?(Exception?e)?{
          ????????????e.printStackTrace();
          ????????}
          ????}

          ????/**
          ?????*?異常返回通知,用于攔截異常日志信息?連接點拋出異常后執(zhí)行
          ?????*
          ?????*?@param?joinPoint?切入點
          ?????*?@param?e?????????異常信息
          ?????*/

          ????@AfterThrowing(pointcut?=?"operExceptionLogPoinCut()",?throwing?=?"e")
          ????public?void?saveExceptionLog(JoinPoint?joinPoint,?Throwable?e)?{
          ????????//?獲取RequestAttributes
          ????????RequestAttributes?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;
          ????????????//?請求的參數(shù)
          ????????????Map?rtnMap?=?converMap(request.getParameterMap());
          ????????????//?將參數(shù)所在的數(shù)組轉(zhuǎn)換成json
          ????????????String?params?=?JSON.toJSONString(rtnMap);
          ????????????excepLog.setExcRequParam(params);?//?請求參數(shù)
          ????????????excepLog.setOperMethod(methodName);?//?請求方法名
          ????????????excepLog.setExcName(e.getClass().getName());?//?異常名稱
          ????????????excepLog.setExcMessage(stackTraceToString(e.getClass().getName(),?e.getMessage(),?e.getStackTrace()));?//?異常信息
          ????????????excepLog.setOperUserId(UserShiroUtil.getCurrentUserLoginName());?//?操作員ID
          ????????????excepLog.setOperUserName(UserShiroUtil.getCurrentUserName());?//?操作員名稱
          ????????????excepLog.setOperUri(request.getRequestURI());?//?操作URI
          ????????????excepLog.setOperIp(IPUtil.getRemortIP(request));?//?操作員IP
          ????????????excepLog.setOperVer(operVer);?//?操作版本號
          ????????????excepLog.setOperCreateTime(new?Date());?//?發(fā)生異常時間

          ????????????exceptionLogService.insert(excepLog);

          ????????}?catch?(Exception?e2)?{
          ????????????e2.printStackTrace();
          ????????}

          ????}

          ????/**
          ?????*?轉(zhuǎn)換request?請求參數(shù)
          ?????*
          ?????*?@param?paramMap?request獲取的參數(shù)數(shù)組
          ?????*/

          ????public?Map?converMap(Map?paramMap)?{
          ????????Map?rtnMap?=?new?HashMap();
          ????????for?(String?key?:?paramMap.keySet())?{
          ????????????rtnMap.put(key,?paramMap.get(key)[0]);
          ????????}
          ????????return?rtnMap;
          ????}

          ????/**
          ?????*?轉(zhuǎn)換異常信息為字符串
          ?????*
          ?????*?@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注解

          六、操作日志、異常日志查詢功能




          ---END---

          文末福利



          瀏覽 54
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日韩va亚洲va欧美va清高 | 国产成人AV电影在线观看 | 天天日天天操天天日 | 一级卡a毛 | 无码囯无精品毛片大码 |