使用Spring AOP 來記錄使用者操作日誌並存儲到資料庫中
之前要做一個記錄使用者操作的日誌記錄,找了很多方法,最後選擇使用spring AOP來實現。由於是要記錄使用者操作的日誌,所以我使用的是返回通知(@AfterReturning),只有在前端呼叫了我後端的介面併成功返回,才呼叫我的切面方法記錄使用者的操作儲存到資料庫中。
LogAnnotation.java
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.springframework.data.mongodb.core.mapping.Document; /** * 日誌 * @author ** * */ @Target({ElementType.PARAMETER,ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Document public @interface LogAnnotation { /** 日誌描述 */ String description() default ""; /** 業務型別 */ int bizID(); }
切面類
LogAspect.java
@Aspect @Component @SuppressWarnings({ "unchecked", "unused", "rawtypes" }) public class LogAspect { // 注入service,用來將日誌資訊儲存在資料庫 這是我的service,你只需要注入你自己的service就行 @Resource private OprLogDaoService oprLogDaoService; //在**處填入你的LogAnnotation所在的包 //此程式碼是攔截所有使用了LogAnnotation註解的介面 @Pointcut("@annotation(**.LogAnnotation)") // 定義一個切點 private void accAspect() { } //返回通知 @AfterReturning(pointcut= "accAspect()",returning="result") public void around(JoinPoint joinPoint, Object result) throws Throwable { HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()) .getRequest(); String classType = joinPoint.getTarget().getClass().getName(); Class<?> clazz = Class.forName(classType); String clazzName = clazz.getName(); // 攔截的方法名稱。當前正在執行的方法 String methodName = joinPoint.getSignature().getName(); // 獲取方法的引數 Object[] args = joinPoint.getArgs(); // 獲取傳入引數的鍵值對 Map<String, Object> map = (Map<String, Object>) LogUtil.getFieldsName(this.getClass(), clazzName, methodName, args); // 將request中的引數轉化為鍵值對,方便取出 Map<String, Object> map2 = (Map<String, Object>) map.get("request"); String resultArgs = result.toString(); // 獲取返回方法的引數 JSONObject jasonObject = JSONObject.fromObject(resultArgs); Map mapResult = (Map) jasonObject; //將返回的result引數取出 Map<String, Object> res = (Map<String, Object>) mapResult.get("result"); //這樣傳入的引數和返回的引數都已變成Map物件 //通過直接 .get("欄位名")的方式將對應的欄位值取出 //比如取出使用者的使用者名稱ID Integer userID = (Integer) mapResult.get("userID"); // 常見日誌實體物件 OprLog oprLog = new OprLog(); //根據自己定義的實體類的屬性將資料填入 OprLog.setUserID(userID); OprLog.set...(); // 儲存進資料庫 //開頭定義的service,這邊使用你自己的service就行了 oprLogDaoService.addLog(oprLog); }
接下來就是在controller上添加註解了
只需要在介面上添加註解@LogAnnotation(description = "日誌記錄", bizID = 1) bizID是我自己定義的你也可以定義成String型別,寫上方法名。
@LogAnnotation(description = "日誌記錄", bizID = 1)
@RequestMapping(value = "/Test", method = RequestMethod.POST)
獲取自定義註解內容的方法
可以直接在註解上寫使用者的操作內容(修改、新增之類的)
/** * 獲取註解內容 * @param joinPoint * @return * @throws Exception */ public static Integer getMthodRemark(JoinPoint joinPoint) throws Exception { String targetName = joinPoint.getTarget().getClass().getName(); String methodName = joinPoint.getSignature().getName(); Object[] arguments = joinPoint.getArgs(); Class targetClass = Class.forName(targetName); Method[] method = targetClass.getMethods(); Integer bizId = null;//此處可以根據你想要的型別來修改 for (Method m : method) { if (m.getName().equals(methodName)) { Class[] tmpCs = m.getParameterTypes(); if (tmpCs.length == arguments.length) { ControllerLogAnnotation cla = m.getAnnotation(ControllerLogAnnotation.class); if (cla != null) { bizId = cla.bizID(); } break; } } } return bizId; } }
另外還有一些工具類的方法
這個是轉換成map物件的方法
public static Map<String, Object> getFieldsName(Class cls, String clazzName, String methodName, Object[] args)throws Exception {
Map<String, Object> map = new HashMap<String, Object>();
ClassPool pool = ClassPool.getDefault();
ClassClassPath classPath = new ClassClassPath(cls);
pool.insertClassPath(classPath);
CtClass cc = pool.get(clazzName);
CtMethod cm = cc.getDeclaredMethod(methodName);
MethodInfo methodInfo = cm.getMethodInfo();
CodeAttribute codeAttribute = methodInfo.getCodeAttribute();
LocalVariableAttribute attr = (LocalVariableAttribute) codeAttribute.getAttribute(LocalVariableAttribute.tag);
if (attr == null) {
// exception
}
int pos = Modifier.isStatic(cm.getModifiers()) ? 0 : 1;
for (int i = 0; i < cm.getParameterTypes().length; i++) {
map.put(attr.variableName(i + pos), args[i]);// paramNames即引數名
}
return map;
}
最後在springMVCxml中加入
<context:component-scan
//LogAspect 在aop中
base-package="切面所在的包例如(a.b.aop)"></context:component-scan>
<aop:aspectj-autoproxy expose-proxy="true"></aop:aspectj-autoproxy>
另外還有一些依賴的jar包,需要的jar包都可以在百度中搜索到,用的時候沒有可以在百度查詢jar包依賴,放在maven專案中的pom.xml檔案中。
相關推薦
使用Spring AOP 來記錄使用者操作日誌並存儲到資料庫中
之前要做一個記錄使用者操作的日誌記錄,找了很多方法,最後選擇使用spring AOP來實現。由於是要記錄使用者操作的日誌,所以我使用的是返回通知(@AfterReturning),只有在前端呼叫了我後端的介面併成功返回,才呼叫我的切面方法記錄使用者的操作儲存到資料庫中。 L
自定義註解+Spring AOP實現記錄使用者操作日誌
一、背景 專案中需要對使用者的各種操作做詳細的操作日誌記錄,需要記錄使用者操作的操作模組、具體操作以及操作的資料記錄ID等。 若寫一個方法去儲存操作,則需要每次手動去呼叫。由於是非業務性的操作,並且大量的重複操作,Spring AOP就能很好的解決這個問題。
spring boot log4j2 自定義級別日誌並存儲,超詳細
由於需要一些業務日誌,本來是用的註解,然後用spring aop獲取註解的形式來記錄,但是由於最開始的時候沒有統一controller 方法的引數,引數資料,細緻到id不太好記錄。於是想到了log4j的形式儲存資料庫,但log4j的形式記錄會記錄所有級別的日誌,即使指定日誌級
[轉]spring boot 攔截器 或 Spring AOP 方式記錄請求日誌
選擇使用攔截器實現,在實現中遇到兩個個問題: a. POST請求 @RequestBody 傳的引數不知怎麼獲取? b. 返回結果如何獲取? c.攔截器中service 無法注入;(已解決) 不知道有沒有人遇到這種情況,攔截器沒有解決上述問題,後來使用 spring
Spring AOP面向切面程式設計之日誌記錄
實際專案中我們往往需要將一些重要的操作,以日誌的形式進行儲存,當機器宕機的時候,可以通過查詢日誌,定位出錯位置,方便恢復。 1:首先匯入spring支援的AOP架包 2:編寫將要進行切面工作的類 /** * */ package com.zhiyou100.aspect; i
spring aop切點記錄日誌到mongodb 註解版
package com.jk.aspectj; import java.util.Date; import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang3.StringUtil
spring aop實現(使用者操作記錄,一場記錄)
第一步定義兩個註解: Java程式碼 複製程式碼 package com.annotation; import java.lang.annotation.*; /** *自定義註解 攔截Controller */ @Target({ElementType.PA
Spring Boot 使用攔截器記錄使用者操作日誌
前言 上篇檔案主要是講了如何使用aop記錄使用者操作日誌,這篇檔案將介紹如何使用攔截器記錄操作日誌 匯入依賴 在處理請求引數時需要用到Json,其他依賴請檢視原始碼 <!-- Json解析 --> <dependency> <
Spring Boot從入門到實戰:整合AOPLog來記錄介面訪問日誌
日誌是一個Web專案中必不可少的部分,藉助它我們可以做許多事情,比如問題排查、訪問統計、監控告警等。一般通過引入slf4j的一些實現框架來做日誌功能,如log4j,logback,log4j2,其效能也是依次增強。在springboot中,預設使用的框架是logback。我們經常需要在方法開頭或結尾加日誌記錄
javaWEB SSM AOP+註解保存操作日誌
java aop aop保存日誌 aop異步保存日誌 javaweb 本篇文章的誕生離不開這篇文章的作者:http://blog.csdn.net/czmchen/article/details/42392985。前言操作日誌在javaWeb的業務系統中是在是太常見的功能了,主要記錄用戶再
MySQL記錄使用者操作日誌
有時,我們想追蹤某個資料庫操作記錄,如想找出是誰操作了某個表(比如誰將欄位名改了)。 二進位制日誌記錄了操作記錄,執行緒號等資訊,但是卻沒有記錄使用者資訊,因此需要結合init-connect來實現追蹤。 init-connect,在每次連線的初始化階段,記錄下這個連線的使用者,和conne
Spring AOP 自定義註解實現日誌管理
目錄 一、配置檔案 二、新建一個日誌實體類Log 三、編寫 service 層 四、編寫 service 層的實現 serviceimpl 五、自定義註解類 六、編寫切面類 七、spring + aop 需要的 jar 包 部落格的程式碼是基於 SSM 環境編寫的
spring-AOP+自定義註解實現日誌管理(註解方式實現)
一、場景 後臺管理系統中,管理員作業系統時生成日誌儲存在資料庫中。 二、實現 1、jar包依賴 <!-- https://mvnrepository.com/artifact/org.springframework/spring-aop --> <dependency&
關於系統記錄使用者操作日誌及物件變更問題
mysql匯入出錯懷疑是特殊字元導致一道白光回到白雲城看看經驗149級54的經驗只要能找到類似的精英怪聚集點相信一天時間就能升到150級到時候裝備上我的仙器烈魂劍哈哈哈簡直拉風到了極點啊mysql匯入出錯懷疑是特殊字元導
利用Spring AOP自定義註解解決日誌和簽名校驗
一、需解決的問題 部分API有簽名引數(signature),Passport首先對簽名進行校驗,校驗通過才會執行實現方法。 第一種實現方式(Origin):在需要簽名校驗的接口裡寫校驗的程式碼,例如: boolean isValid = accountService.val
PHP記錄使用者操作日誌記錄
<?php header("Content-type: text/html; charset=utf-8"); error_reporting(0);//關閉所有的錯誤資訊,不會顯示,如果
log4j用來儲存使用者操作日誌
開發條件:log4j.properties 配置檔案 +sqlserver資料庫所做功能:能夠儲存使用者在登入狀態下所做的操作準備步驟:1.log4j.properties配置檔案中的資訊:log4j.rootLogger=debug,DB,console#log4j.lo
使用Spring MVC攔截器管理操作日誌
通過攔截器記錄操作日誌,將操作日誌儲存到資料庫中,實現這個功能需要我們將curd操作的URL規範化,比如:新增是以add或者insert開始,修改是update開頭,刪除則是delete開頭。 第一步:編寫攔截器類,程式碼如下: package com.
基於Springboot的Spring AOP學習記錄
前段時間各種面試,aop問到就蒙逼,所以結合新學的springboot重新理一下這玩意兒,很重要啊 一、AOP概述 AOP(面對切面程式設計)是對OOP(面向物件程式設計)的補充,總體來說,程式設計正規化包含:面向過程程式設計、面向物件程式設計、函數語言
JAVA記錄使用者操作日誌
import java.io.BufferedWriter; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io