JAVA SSM+AOP方式编写后台操作日志(简单版)
描述:
项目环境:SMM框架 MAVEN项目
参考项目:参考地址URL
Jar包下载地址:
https://mvnrepository.com/artifact/aopalliance/aopalliance
https://mvnrepository.com/artifact/org.aspectj/aspectjweaver
https://mvnrepository.com/artifact/org.aspectj/aspectjrt
-
配置项目pom文件 (注意版本适配) 建议使用较高版本
-
配置 spring-mvc.xml (配置文件)
-
编写 AOP日志的配置
详细如下:
1.package com.xj.ssm.utils;
2.
3.import javax.servlet.http.HttpSession;
4.
5.import org.aspectj.lang.ProceedingJoinPoint;
6.import org.aspectj.lang.annotation.Around;
7.import org.aspectj.lang.annotation.Aspect;
8.import org.aspectj.lang.annotation.Pointcut;
9.import org.springframework.beans.factory.annotation.Autowired;
10.import org.springframework.stereotype.Component;
11.import javax.servlet.http.HttpServletRequest;
12.import org.aspectj.lang.Signature;
13.import org.aspectj.lang.reflect.MethodSignature;
14.
15.import java.lang.reflect.Method;
16.import java.net.Inet4Address;
17.import java.net.InetAddress;
18.import java.net.UnknownHostException;
19.import java.util.ArrayList;
20.import java.util.List;
21.
22.import org.springframework.web.context.request.ServletRequestAttributes;
23.import org.springframework.web.context.request.RequestContextHolder;
24.
25.import com.xj.ssm.pojo.OperationJournalDo;
26.import com.xj.ssm.pojo.Operator;
27.import com.xj.ssm.service.OperationJournalService;
28.
29./**
30. * Aop日志的配置
31. *
32. */
33.@Component
34.@Aspect
35.public class OperationLog {
36.
37. // 注入service
38. @Autowired
39. private OperationJournalService os;
40.
41. // 配置接入点
42. @Pointcut("execution(* com.xj.ssm.controller..*.*(..))")
43. private void controllerAspect() {}// 定义一个切入点
44.
45. @Around("controllerAspect()")
46. public Object around(ProceedingJoinPoint pjp) throws Throwable {
47. //System.out.println("进入了aop界面工程");
48. //System.out.println("pjp===" + pjp);
49.
50. String pjpStr = pjp.toString();
51.
52. OperationJournalDo operationJournal = new OperationJournalDo();
53.
54. if (!pjpStr.equals("execution(String com.xj.ssm.controller.LoginController.showLogin())")) {
55. if (!pjpStr.contains("execution(ResponseResult com.xj.ssm.controller.LoginController.login(HttpSession,String,String))")) {
56. System.out.println("进入AOP操作日志);
57.
58. HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
59. HttpSession session = request.getSession();
60. Operator operator = (Operator) session.getAttribute("operator");
61. //System.out.println("operator==="+operator);
62. operationJournal.setOperatorId(operator.getId());
63. operationJournal.setOperatorName(operator.getUsername());
64. // 创建人
65. operationJournal.setCreateUser(operator.getUsername());
66.
67. // 获取客户端ip
68. try {
69. InetAddress ip4 = Inet4Address.getLocalHost();
70. operationJournal.setiP(ip4.getHostAddress().toString());
71. //System.out.println("ipv4===" + ip4.getHostAddress());
72. } catch (UnknownHostException e) {
73. e.printStackTrace();
74. }
75. }
76. }
77.
78. // 方法通知前获取时间,来计算模块执行时间的
79. long start = System.currentTimeMillis();
80. //System.out.println("方法通知前获取时间==="+start);
81. // 拦截的实体类,就是当前正在执行的controller
82. Object target = pjp.getTarget();
83. // 拦截的方法名称,当前正在执行的方法
84. String methodName = pjp.getSignature().getName();
85. // 拦截的方法参数
86. Object[] args = pjp.getArgs();
87.
88. // 获取入参 , 入参的时候获取了session,如果开启一下内容 去掉session信息
89. /*String beforeChange = "";
90. System.out.println("args==="+args+",args.length==="+args.length);
91. // && args[0].getClass() == String.class
92. if (args != null && args.length > 0) {
93. System.out.println("args[0].getClass()==="+args[0].getClass());
94. System.out.println("args[0]==="+args[0]);
95. if (!args[0].getClass().equals("class org.apache.catalina.session.StandardSessionFacade")) {
96. for (Object object : args) {
97. //System.out.println(object instanceof HttpServletRequest);
98. if (object != null && object != "") {
99. System.out.println("循环入参object==="+object);
100. beforeChange += object+",";
101. }
102. }
103. beforeChange = beforeChange.substring(0, beforeChange.length() - 1);
104. System.out.println("入参==="+beforeChange);
105. }
106. }
107. operationJournal.setBeforeChange(beforeChange);*/
108. // 拦截的放参数类型
109. Signature sig = pjp.getSignature();
110. //System.out.println("拦截的方法名称==="+methodName+",拦截的方法参数==="+args+",拦截的放参数类型==="+sig);
111. MethodSignature msig = null;
112. if (!(sig instanceof MethodSignature)) {
113. throw new IllegalArgumentException("该注解只能用于方法");
114. }
115.
116. msig = (MethodSignature) sig;
117. Class[] parameterTypes = msig.getMethod().getParameterTypes();
118. //System.out.println("parameterTypes参数==="+parameterTypes);
119.
120. Object object = null;
121. // 获得被拦截的方法
122. Method method = null;
123. try {
124. method = target.getClass().getMethod(methodName, parameterTypes);
125. } catch (NoSuchMethodException e1) {
126. // TODO Auto-generated catch block
127. e1.printStackTrace();
128. } catch (SecurityException e1) {
129. // TODO Auto-generated catch block
130. e1.printStackTrace();
131. }
132. //System.out.println("method方法===" + method);
133. if (method != null) {
134. if (method.isAnnotationPresent(OperationJournalLog.class)) {
135. //System.out.println("OperationJournalLog===" + OperationJournalLog.class);
136. // 操作模块方法名
137. operationJournal.setResouseMethod(methodName);
138.
139. OperationJournalLog systemlog = method.getAnnotation(OperationJournalLog.class);
140. operationJournal.setResouseName(systemlog.resouseName());
141. operationJournal.setType(Integer.parseInt(systemlog.type()));
142. operationJournal.setResouseModular(systemlog.resouseModular());
143.
144. try {
145. object = pjp.proceed();
146. long end = System.currentTimeMillis();
147. //将计算好的时间保存在实体中
148. operationJournal.setResponseTime(""+(end-start));
149. operationJournal.setStatus(1);// 执行成功
150. //保存进数据库
151. os.insertOperationInfomations(operationJournal);
152. /*System.out.println("没切完");*/
153. } catch (Throwable e) {
154. // TODO Auto-generated catch block
155. long end = System.currentTimeMillis();
156. operationJournal.setResponseTime(""+(end-start));
157. operationJournal.setStatus(2);// 执行失败
158. os.insertOperationInfomations(operationJournal);
159. /*System.out.println("切切切");*/
160. }
161.
162. } else {// 没有包含注解
163. object = pjp.proceed();
164. }
165.
166. } else { // 不需要拦截直接执行
167. object = pjp.proceed();
168. }
169.
170. /* System.out.println("切完了"); */
171. return object;
172.
173. }
174.
175.
176.}
-
系统日志的自定义注解
-
Controller层使用方式
-
页面基本展示
-
遇到的问题(注:这个图片找不到出处了 抱歉!!!)