先看效果
上代码
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
@Table(name="syslog")
@Data
public class SysLog implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private Integer id;
private String username; //用户名
private String operDesc; //操作描述
private String operModule; //操作模块
private String operType; //操作类型
private String method; //方法名
private String params; //参数
private String ip; //ip地址
@Column(name="createDate")
private String createDate; //操作时间
}
//自定义注解
import java.lang.annotation.*;
@Target(ElementType.METHOD) //注解放置的目标位置,METHOD是可注解在方法级别上
@Retention(RetentionPolicy.RUNTIME) //注解在哪个阶段执行
public @interface MyLog {
String operModule() default "";
String operType() default "";
String operDesc() default "";
}
package mlt.boot.log;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;
import javax.servlet.http.HttpServletRequest;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSONObject;
import mlt.boot.entity.SysLog;
import mlt.boot.mapper.SysLogMapper;
@Aspect
@Component
public class SysLogAspect {
@Autowired
private SysLogMapper sysLogMapper;
@Autowired
HttpServletRequest request;
//定义切点 @Pointcut
//在注解的位置切入代码
@Pointcut("@annotation(mlt.boot.log.MyLog)")
public void logPoinCut() {
}
/**
* 切面 配置通知
* 根据需要在切入点不同位置的切入内容
* 使用@Before在切入点开始处切入内容
* 使用@After在切入点结尾处切入内容
* 使用@AfterReturning在切入点return内容之后切入内容(可以用来对处理返回值做一些加工处理)
* 使用@Around在切入点前后切入内容,并自己控制何时执行切入点自身的内容
* 使用@AfterThrowing用来处理当切入内容部分抛出异常之后的处理逻辑
*/
//@AfterReturning("logPoinCut()") //如果出现异常,则捕获不到
@Before("logPoinCut()")
public void saveSysLog(JoinPoint joinPoint) {
//保存日志
SysLog sysLog = new SysLog();
//从切面织入点处通过反射机制获取织入点处的方法
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
//获取切入点所在的方法
Method method = signature.getMethod();
//获取操作
MyLog myLog = method.getAnnotation(MyLog.class);
sysLog.setOperDesc(myLog.operDesc());
sysLog.setOperModule(myLog.operModule());
sysLog.setOperType(myLog.operType());
//获取请求的类名
String className = joinPoint.getTarget().getClass().getName();
//记录一下哪个类下面的哪个请求
sysLog.setMethod(className+":"+request.getRequestURI());
Enumeration<String> paramter = request.getParameterNames();
JSONObject json = new JSONObject();
while (paramter.hasMoreElements()) {
String str = (String) paramter.nextElement();
json.put(str, request.getParameter(str));
}
sysLog.setParams(json.toJSONString());
sysLog.setCreateDate(new SimpleDateFormat().format(new Date()));
//获取用户名
sysLog.setUsername("xiaosb");
//获取用户ip地址
sysLog.setIp(request.getRemoteAddr());
//保存
sysLogMapper.insertSelective(sysLog);
}
}
使用方法
下面的是记录异常日志(自己模拟的异常) 别问 问就是借鉴的
@Table(name="ExceptionLog")
@Data
public class ExceptionLogEntity {
private Integer Id;
private String excRequParam;
private String excName;
private String excMessage;
private String operUserId;
private String operUserName;
private String operMethod;
private String operIp;
private String operCreateTime;
}
/**
* 异常记录
*/
@Pointcut("execution(* mlt.boot.controller..*.*(..))")
public void operExceptionLogPoinCut() {
}
@Autowired
private ExceptionLogMapper exceptionLogMapper;
@AfterThrowing(pointcut = "operExceptionLogPoinCut()", throwing = "e")
public void saveExceptionLog(JoinPoint joinPoint, Throwable e) {
// 获取RequestAttributes
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
// 从获取RequestAttributes中获取HttpServletRequest的信息
HttpServletRequest request = (HttpServletRequest) requestAttributes
.resolveReference(RequestAttributes.REFERENCE_REQUEST);
ExceptionLogEntity excepLog = new ExceptionLogEntity();
try {
// 获取请求的类名
String className = joinPoint.getTarget().getClass().getName();
// 获取请求的方法名
String methodName = className+":"+request.getRequestURI();
// 请求的参数
Enumeration<String> paramter = request.getParameterNames();
JSONObject json = new JSONObject();
while (paramter.hasMoreElements()) {
String str = (String) paramter.nextElement();
json.put(str, request.getParameter(str));
}
excepLog.setExcRequParam(json.toJSONString()); // 请求参数
excepLog.setOperMethod(methodName); // 请求方法名
excepLog.setExcName(e.getClass().getName()); // 异常名称
excepLog.setExcMessage(stackTraceToString(e.getClass().getName(), e.getMessage(), e.getStackTrace())); // 异常信息
excepLog.setOperUserId("1"); // 操作员ID
excepLog.setOperUserName("xiaosb"); // 操作员名称
excepLog.setOperIp(request.getRemoteAddr()); // 操作员IP
excepLog.setOperCreateTime(new Date().toLocaleString()); // 发生异常时间
exceptionLogMapper.insertSelective(excepLog);
} catch (Exception e2) {
e2.printStackTrace();
}
}
public String stackTraceToString(String exceptionName, String exceptionMessage, StackTraceElement[] elements) {
StringBuffer strbuff = new StringBuffer();
for (StackTraceElement stet : elements) {
strbuff.append(stet + "\n");
}
String message = exceptionName + ":" + exceptionMessage + "\n\t" + strbuff.toString();
return message;
}