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

网友投稿 228 2023-02-25


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(IntegeAwurIgr 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

org.aspectj

aspectjrt

1.7.4

&AwurIglt;/dependency>

org.aspectj

aspectjweaver

1.7.4

cglib

cglib

2.1_3

org.springframework

spring-aop

4.2.5.RELEASE

这里要求项目使用的是jdk1.7

3:springServlet-mvc.xml

加上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数据库都有记录


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:BootStrap自定义popover,点击区域隐藏功能的实现
下一篇:基于java文本复制的7种方式总结
相关文章

 发表评论

暂时没有评论,来抢沙发吧~