欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

aop注解方式实现全局日志管理方法

程序员文章站 2023-12-01 09:30:22
1:日志实体类 public class syslog { /** */ private integer id; /** 日志描述*/ priva...

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
@component
public 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注解方式实现全局日志管理方法

以上这篇aop注解方式实现全局日志管理方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。