最近项目新增一个功能,需要把用户的操作都记录到数据库,于是在实现功能之后在这里分享
1.新建操作记录实体类
package com.xinbiao.model;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("OPERATION_LOG_INFO")
public class OperationLogInfo {
@TableId
private Long operationLogId;
//操作人
private String userName;
//访问接口
private String requestUri;
//接口描述
private String apiMessage;
//访问方法
private String requestMethod;
//请求参数
private String requestParam;
//访问时间
private String operationTime;
//操作结果
private String result;
}
大家请根据自己的需求增减字段,然后将你的dao service serviceImpl controller创建好
2.导入AOP所需依赖
<dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.9.1</version> </dependency>
3.编写自定义注解,用于描述接口功能
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Describe {
String value() default "";
}
4.编写配置文件
<!-- 开启注解驱动 -->
<aop:aspectj-autoproxy/>
<!-- 扫描切面类所在的包 -->
<context:component-scan base-package="com.xinbiao.AOP"/>
5.编写切面
package com.xinbiao.AOP;
import com.alibaba.fastjson.JSON;
import com.xinbiao.AOP.Describe;
import com.xinbiao.commons.DateUtil;
import com.xinbiao.commons.IdWorker;
import com.xinbiao.model.OperationLogInfo;
import com.xinbiao.model.PlatformAccount;
import com.xinbiao.service.OperationLogInfoService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
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 org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.lang.reflect.Method;
import java.util.Date;
@Aspect//被注解类的会被解析为一个切面
@Component
public class LoggingAspect {
@Autowired
OperationLogInfoService operationLogInfoService;
@Pointcut("execution(* com.xinbiao.controller.*.*(..))")
public void controllerPointcut() {
}
@AfterReturning(pointcut = "controllerPointcut()", returning = "result")
public void logAfterReturning(JoinPoint joinPoint, Object result) {
System.out.println("切面记录日志开始执行");
// 获取当前用户的用户名
String username = getUsernameFromSession();
// 获取请求信息
String requestUrl = joinPoint.getSignature().toShortString();
String requestMethod = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();
String requestParams = JSON.toJSONString(args);
// 获取操作描述
String operationDescription = getOperationDescription(joinPoint);
// 获取操作时间
String operationTime = DateUtil.dateToString(new Date());
// 获取操作状态,这里假设根据返回结果是否为空判断操作是否成功
String status = (result != null) ? "成功" : "失败";
// 保存操作日志
OperationLogInfo operationLogInfo = new OperationLogInfo(
IdWorker.getId(), username, requestMethod, operationDescription,
requestUrl , requestParams, operationTime, status);
operationLogInfoService.save(operationLogInfo);
System.out.println("切面记录日志执行完成");
}
private String getUsernameFromSession() {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
HttpSession session = request.getSession(false);
if (session != null) {
Object tokenObject = session.getAttribute("token");
if (tokenObject != null && tokenObject instanceof PlatformAccount) {
PlatformAccount platformAccount = (PlatformAccount) tokenObject;
return platformAccount.getUserName();
}
}
return "";
}
private String getOperationDescription(JoinPoint joinPoint) {
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
Method method = methodSignature.getMethod();
if (method.isAnnotationPresent(Describe.class)) {
Describe annotation = method.getAnnotation(Describe.class);
return annotation.value();
}
return "暂无描述";
}
}
实现效果: