aop註解方式實現全域日誌管理方法,aop管理方法

來源:互聯網
上載者:User

aop註解方式實現全域日誌管理方法,aop管理方法

1:日誌實體類

public class SysLog { /** */ private Integer id; /** 日誌描述*/ private String description; /** 執行的方法*/ private String method; /** 日誌類型 0:動作記錄;1:異常日誌*/ private Integer logType; /** 用戶端請求的ip地址*/ private String requestIp; /** 異常代碼*/ private String exceptionCode; /** 異常詳細資料*/ private String exceptionDetail; /** 請求參數*/ private String params; /** 操作人*/ private String createBy; /** 操作時間*/ private String createDate; public Integer getId() {  return id; } public void setId(Integer id) {  this.id = id; } public String getDescription() {  return description; } public void setDescription(String description) {  this.description = description; } public String getMethod() {  return method; } public void setMethod(String method) {  this.method = method; } public Integer getLogType() {  return logType; } public void setLogType(Integer logType) {  this.logType = logType; } public String getRequestIp() {  return requestIp; } public void setRequestIp(String requestIp) {  this.requestIp = requestIp; } public String getExceptionCode() {  return exceptionCode; } public void setExceptionCode(String exceptionCode) {  this.exceptionCode = exceptionCode; } public String getExceptionDetail() {  return exceptionDetail; } public void setExceptionDetail(String exceptionDetail) {  this.exceptionDetail = exceptionDetail; } public String getParams() {  return params; } public void setParams(String params) {  this.params = params; } public String getCreateBy() {  return createBy; } public void setCreateBy(String createBy) {  this.createBy = createBy; } public String getCreateDate() {  return createDate; } public void setCreateDate(String createDate) {  this.createDate = createDate; }}

2:maven需要的jar

<dependency>    <groupId>org.aspectj</groupId>    <artifactId>aspectjrt</artifactId>    <version>1.7.4</version>   </dependency>  <dependency>    <groupId>org.aspectj</groupId>    <artifactId>aspectjweaver</artifactId>    <version>1.7.4</version>  </dependency> <dependency>    <groupId>cglib</groupId>    <artifactId>cglib</artifactId>    <version>2.1_3</version>  </dependency><dependency>  <groupId>org.springframework</groupId>  <artifactId>spring-aop</artifactId>  <version>4.2.5.RELEASE</version></dependency> 

這裡要求項目使用的是jdk1.7

3:springServlet-mvc.xml

<!--proxy-target-class="true"強制使用cglib代理 如果為false則spring會自動選擇--> <aop:aspectj-autoproxy proxy-target-class="true"/> 

加上proxy-target-class="true"是為了可以攔截controller裡面的方法

4:定義切面,我這裡主要寫前置通知和異常通知

下面開始自訂註解

import java.lang.annotation.*;@Target({ElementType.PARAMETER, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Log {/** 要執行的操作類型比如:add操作 **/  public String operationType() default "";  /** 要執行的具體操作比如:添加使用者 **/  public String operationName() default "";}

切面類

import java.lang.reflect.Method;import java.text.SimpleDateFormat;import java.util.Arrays;import java.util.Date;import javax.annotation.Resource;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpSession;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.After;import org.aspectj.lang.annotation.AfterReturning;import org.aspectj.lang.annotation.AfterThrowing;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.aspectj.lang.annotation.Pointcut;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.stereotype.Component;import org.springframework.web.context.request.RequestContextHolder;import org.springframework.web.context.request.ServletRequestAttributes;import com.gtcity.user.model.SysLog;import com.gtcity.user.model.SysUser;import com.gtcity.user.service.SysLogService;/** * @author panliang * @version 建立時間:2017-3-31  * @desc 切點類  * */@Aspect@Componentpublic class SystemLogAspect {//注入Service用於把日誌儲存資料庫 @Resource private SysLogService systemLogService;private static final Logger logger = LoggerFactory.getLogger(SystemLogAspect. class); //Controller層切點 //第一個*代表所有的傳回值類型//第二個*代表所有的類//第三個*代表類所有方法//最後一個..代表所有的參數。 @Pointcut("execution (* com.gtcity.web.controller..*.*(..))")  public void controllerAspect() {  }   /** *  * @author: panliang * @time:2017-3-31 下午2:22:16 * @param joinPoint 切點 * @describtion:前置通知 用於攔截Controller層記錄使用者的操作  */ @Before("controllerAspect()") public void doBefore(JoinPoint joinPoint) {/* System.out.println("==========執行controller前置通知==============="); if(logger.isInfoEnabled()){ logger.info("before " + joinPoint); }*/  HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();    HttpSession session = request.getSession();    //讀取session中的使用者    SysUser user = (SysUser) session.getAttribute("user");    if(user==null){   user=new SysUser();   user.setUserName("非註冊使用者");   }   //請求的IP    String ip = request.getRemoteAddr();   try {         String targetName = joinPoint.getTarget().getClass().getName();     String methodName = joinPoint.getSignature().getName();     Object[] arguments = joinPoint.getArgs();     Class targetClass = Class.forName(targetName);     Method[] methods = targetClass.getMethods();    String operationType = "";    String operationName = "";    for (Method method : methods) {      if (method.getName().equals(methodName)) {       Class[] clazzs = method.getParameterTypes();       if (clazzs.length == arguments.length) {        operationType = method.getAnnotation(Log.class).operationType();       operationName = method.getAnnotation(Log.class).operationName();       break;       }      }     }    //*========控制台輸出=========*//     System.out.println("=====controller前置通知開始=====");     System.out.println("要求方法:" + (joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()")+"."+operationType);     System.out.println("方法描述:" + operationName);     System.out.println("請求人:" + user.getUserName());     System.out.println("請求IP:" + ip);     //*========資料庫日誌=========*//     SysLog log = new SysLog();     log.setDescription(operationName);     log.setMethod((joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()")+"."+operationType);     log.setLogType(0);     log.setRequestIp(ip);     log.setExceptionCode(null);     log.setExceptionDetail( null);     log.setParams( null);     log.setCreateBy(user.getUserName());    log.setCreateDate(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));     log.setRequestIp(ip);    //儲存資料庫     systemLogService.insert(log);     System.out.println("=====controller前置通知結束=====");    } catch (Exception e) {     //記錄本地異常日誌     logger.error("==前置通知異常==");     logger.error("異常資訊:{}", e.getMessage());    }    }      /** *  * @author: panliang * @time:2017-3-31 下午2:24:36 * @param joinPoint 切點  * @describtion:異常通知 用於攔截記錄異常日誌  */  @AfterThrowing(pointcut = "controllerAspect()", throwing="e")   public void doAfterThrowing(JoinPoint joinPoint, Throwable e) {     HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();    HttpSession session = request.getSession();    //讀取session中的使用者    SysUser user = (SysUser) session.getAttribute("user");    if(user==null){    user=new SysUser();    user.setUserName("非註冊使用者");   }   //請求的IP    String ip = request.getRemoteAddr();      String params = "";    if (joinPoint.getArgs() != null && joinPoint.getArgs().length > 0) {       params=Arrays.toString(joinPoint.getArgs());   }    try {         String targetName = joinPoint.getTarget().getClass().getName();     String methodName = joinPoint.getSignature().getName();     Object[] arguments = joinPoint.getArgs();     Class targetClass = Class.forName(targetName);     Method[] methods = targetClass.getMethods();    String operationType = "";    String operationName = "";    for (Method method : methods) {      if (method.getName().equals(methodName)) {       Class[] clazzs = method.getParameterTypes();       if (clazzs.length == arguments.length) {        operationType = method.getAnnotation(Log.class).operationType();       operationName = method.getAnnotation(Log.class).operationName();       break;       }      }     }    /*========控制台輸出=========*/     System.out.println("=====異常通知開始=====");     System.out.println("異常代碼:" + e.getClass().getName());     System.out.println("異常資訊:" + e.getMessage());     System.out.println("異常方法:" + (joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()")+"."+operationType);     System.out.println("方法描述:" + operationName);     System.out.println("請求人:" + user.getUserName());     System.out.println("請求IP:" + ip);     System.out.println("請求參數:" + params);     //==========資料庫日誌=========     SysLog log = new SysLog();    log.setDescription(operationName);     log.setExceptionCode(e.getClass().getName());     log.setLogType(1);     log.setExceptionDetail(e.getMessage());     log.setMethod((joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()"));     log.setParams(params);     log.setCreateBy(user.getUserName());     log.setCreateDate(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));     log.setRequestIp(ip);     //儲存資料庫     systemLogService.insert(log);     System.out.println("=====異常通知結束=====");    } catch (Exception ex) {     //記錄本地異常日誌     logger.error("==異常通知異常==");     logger.error("異常資訊:{}", ex.getMessage());    }    //==========記錄本地異常日誌==========    logger.error("異常方法:{}異常代碼:{}異常資訊:{}參數:{}", joinPoint.getTarget().getClass().getName() + joinPoint.getSignature().getName(), e.getClass().getName(), e.getMessage(), params);    }  }

5:在controller裡面

/** * 根據使用者名稱去找密碼 判斷使用者名稱和密碼是否正確 * @author panliang * @param request * @param response * @throws IOException  */@RequestMapping("/skipPage.do")@Log(operationType="select操作:",operationName="使用者登入")//注意:這個不加的話,這個方法的日誌記錄不會被插入public ModelAndView skipPage(HttpServletRequest request,HttpServletResponse response) throws IOException{ModelAndView result=null;String username = request.getParameter("email");String password = request.getParameter("password");int flag = sysUserService.login(request, username, password);if(flag==1){//登入成功result=new ModelAndView("redirect:/login/dispacher_main.do");}else if(flag==2){//使用者名稱不存在result=new ModelAndView("redirect:/login/login.do?errorCode=1");} else{//密碼不正確result=new ModelAndView("redirect:/login/login.do?errorCode=2");}return result;}

對於想要瞭解其他三種通知的可以參考這篇博文:點擊開啟連結

這樣使用者在訪問後台時,不管是正常訪問還是出現bug資料庫都有記錄

以上這篇aop註解方式實現全域日誌管理方法就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援幫客之家。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.