服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|JavaScript|易语言|

服务器之家 - 编程语言 - JAVA教程 - aop注解方式实现全局日志管理方法

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

2021-03-25 11:02荒唐的程序猿 JAVA教程

下面小编就为大家分享一篇aop注解方式实现全局日志管理方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

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

延伸 · 阅读

精彩推荐