SpringBoot + 自定義註解,實現用戶操作日誌(支持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原稿和原圖片。其它情況一律禁止轉載!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章