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 > < 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注解方式實現全局日志管理方法就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持服務器之家。
原文鏈接:http://blog.csdn.net/pangliang_csdn/article/details/68946506