当前位置: 移动技术网 > IT编程>开发语言>Java > aop注解方式实现全局日志管理方法

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

2019年07月19日  | 移动技术网IT编程  | 我要评论

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注解方式实现全局日志管理方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网