服务器之家

服务器之家 > 正文

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

时间:2021-03-25 11:02     来源/作者:荒唐的程序猿

1:日志实体类

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<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

?
1
2
<!--proxy-target-class="true"强制使用cglib代理 如果为false则spring会自动选择-->
<aop:aspectj-autoproxy proxy-target-class="true"/>

加上proxy-target-class="true"是为了可以拦截controller里面的方法

4:定义切面,我这里主要写前置通知和异常通知

下面开始自定义注解

?
1
2
3
4
5
6
7
8
9
10
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 "";
}

切面类

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
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里面

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
     * 根据用户名去找密码 判断用户名和密码是否正确
     * @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注解方式实现全局日志管理方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持服务器之家。

原文链接:http://blog.csdn.net/pangliang_csdn/article/details/68946506

相关文章

热门资讯

2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全 2019-12-26
yue是什么意思 网络流行语yue了是什么梗
yue是什么意思 网络流行语yue了是什么梗 2020-10-11
背刺什么意思 网络词语背刺是什么梗
背刺什么意思 网络词语背刺是什么梗 2020-05-22
Intellij idea2020永久破解,亲测可用!!!
Intellij idea2020永久破解,亲测可用!!! 2020-07-29
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总 2020-11-13
返回顶部