1、添加aop依赖
<!-- aop日志 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2、新建接口保存数据库的实体类RequestLog.java
package com.example.springboot.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.time.LocalDateTime;
import lombok.Getter;
import lombok.Setter;
/**
* <p>
* 请求日志
* </p>
*
* @author Sca_jie
* @since 2023-09-28
*/
@Getter
@Setter
@TableName("request_log")
public class RequestLog implements Serializable {
private static final long serialVersionUID = 1L;
// 主键-自增
@TableId(value = "number", type = IdType.AUTO)
private Integer number;
// 用户账号
private String id;
// 携带token
private String token;
// 接口路径
private String url;
// 请求类型
private String method;
// 携带参数
private String params;
// ip地址
private String ip;
// 结果
private String result;
// 接口发起时间
private LocalDateTime startDate;
// 接口结束时间
private LocalDateTime endDate;
// 响应耗时
private String responseTime;
}
3、新建一个注解RequestLogAnnotation.java
package com.example.springboot.annotation;
import java.lang.annotation.*;
/**
* 请求记录日志注解
*/
@Target({ElementType.TYPE, ElementType.METHOD}) //注解放置的目标位置,METHOD是可注解在方法级别上
@Retention(RetentionPolicy.RUNTIME) //注解在哪个阶段执行
@Documented
public @interface RequestLogAnnotation {
String value() default "";
}
4、(核心)新建aop面切类RequestLogAspect.java拦截请求并保存日志
package com.example.springboot.common;
import cn.hutool.core.net.NetUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.example.springboot.annotation.RequestLogAnnotation;
import com.example.springboot.entity.RequestLog;
import com.example.springboot.mapper.RequestLogMapper;
import com.example.springboot.utils.CookieUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
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.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.time.LocalDateTime;
/**
* 日志记录
*
*/
@Aspect
@Component
public class RequestLogAspect {
@Autowired(required = false)
RequestLogMapper requestLogMapper;
@Pointcut("@annotation(com.example.springboot.annotation.RequestLogAnnotation)")
public void logPointCut() {
}
// 请求的开始处理时间(不同类型)
Long startTime = null;
LocalDateTime startDate;
@Before("logPointCut()")
public void beforeRequest() {
startTime = System.currentTimeMillis();
startDate = LocalDateTime.now();
}
@AfterReturning(value = "logPointCut()", returning = "result")
public void saveLog(JoinPoint joinPoint, Object result) {
// 获取请求头
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = requestAttributes.getRequest();
HttpServletResponse response = requestAttributes.getResponse();
//从切面织入点处通过反射机制获取织入点处的方法
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
//获取切入点所在的方法
Method method = signature.getMethod();
// 初始化日志表的实体类
RequestLog requestLog = new RequestLog();
//获取操作
RequestLogAnnotation requestLogAnnotation = method.getAnnotation(RequestLogAnnotation.class);
// // 获取@SystemLogAnnotation(value = "用户登录")中的注解value
// if (systemLogAnnotation != null) {
// String value = systemLogAnnotation.value();
// requestLog.setSName(value);
// }
// 获取cookies
Cookie[] cookies = request.getCookies();
if (cookies != null) {
// 获取token
for(Cookie cookie : cookies){
if(cookie.getName().equals("token")){
requestLog.setToken(cookie.getValue());
}
}
// 获取id
String id = CookieUtil.getid(cookies);
if (id != "" | id != null) {
requestLog.setId(id);
}
}
// 区分get和post获取参数
String params = "{}";
if (request.getMethod().equals("GET")) {
params = JSONObject.toJSONString(request.getParameterMap());
} else if (request.getMethod().equals("POST")) {
params = JSONUtil.toJsonStr(joinPoint.getArgs());
}
// 用户Ip
requestLog.setIp(NetUtil.getLocalhostStr());
// 接口请求类型
requestLog.setMethod(request.getMethod());
// 请求参数(区分get和post)
requestLog.setParams(params);
// 请求接口路径
requestLog.setUrl(request.getRequestURI().toString());
// 返回结果
requestLog.setResult(JSONObject.toJSONString(result));
// 请求开始时间
requestLog.setStartDate(startDate);
// 请求结束时间
requestLog.setEndDate(LocalDateTime.now());
// 请求共计时间(ms)
requestLog.setResponseTime(String.valueOf(System.currentTimeMillis() - startTime));
// 保存日志到mysql
requestLogMapper.insert(requestLog);
}
}
5、在对应接口添加注解@RequestLogAnnotation
@RequestLogAnnotation(value = "获取上传记录")
@GetMapping("/getlist")
public Result getlist (@RequestParam(required = false) String id) {
if (id == null) {
return Result.success(404, "参数缺失");
} else {
List<UploadLog> page = uploadLogService.getlist(id);
return Result.success(200, page.toString());
}
}
效果如下