首页 > 开发 > Java > 正文

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

2024-07-13 10:17:07
字体:
来源:转载
供稿:网友

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,注解,全局,日志管理

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


注:相关教程知识阅读请移步到JAVA教程频道。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表