Springboot使用Aop保存接口请求日志到mysql

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;// 携带tokenprivate 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);
//        }// 获取cookiesCookie[] cookies = request.getCookies();if (cookies != null) {// 获取tokenfor(Cookie cookie : cookies){if(cookie.getName().equals("token")){requestLog.setToken(cookie.getValue());}}// 获取idString 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());}// 用户IprequestLog.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));// 保存日志到mysqlrequestLogMapper.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());}}

效果如下

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/125996.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【算法】关于排序你应该知道的一切(下)

和光同尘_我的个人主页 单程孤舟&#xff0c;出云入霞&#xff0c;如歌如吟。 --门孔 八大排序 &#x1f56f;️前言1. 常见排序算法2. 常见排序算法实现2.1. 冒泡排序2.1.1. 基本思想2.1.2. 代码实现2.1.3. 特性 2.2. 快速排序2.2.1. hoare法基本思想代码实现 2.2.2. 快速排…

学习搜狗的workflow,MacBook上如何编译

官网说可以在MacBook上也可以运行&#xff0c;但是编译的时候却有找不到openssl的错误&#xff1a; 看其他博客也有类似的错误&#xff0c;按照类似的思路去解决 问题原因和解决办法 cmake编译的时候&#xff0c;没有找到openssl的头文件&#xff0c;需要设置cmake编译环境下…

命令解释器-Shell

目录 1. 概述 1.1. 概念 1.2. 分类&#xff1a; 1.3. type 命令 1.4.命令执行原理 2. Linux 中的特殊符号 3. 命令别名 3.1. 查看设置的别名 3.2. 常用的别名 3.3. 删除别名 3.6. 注意&#xff08;alias永久化&#xff09;&#xff1a; 4. history 命令历史 例&a…

【状态估计】将变压器和LSTM与卡尔曼滤波器结合到EM算法中进行状态估计(Python代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

直线导轨坏了可以维修吗?

直线导轨是工业自动化设备中常用的零部件&#xff0c;其性能和使用寿命对设备的稳定运行和产能有着直接的影响&#xff0c;在生产中&#xff0c;由于各种原因&#xff0c;直线导轨会出现各种问题&#xff0c;那么&#xff0c;直线导轨的维修方法究竟是怎样的呢&#xff1f;我们…

计算机专业毕业设计项目推荐11-博客项目(Go+Vue+Mysql)

博客项目&#xff08;GoVueMysql&#xff09; **介绍****系统总体开发情况-功能模块****各部分模块实现** 介绍 本系列(后期可能博主会统一为专栏)博文献给即将毕业的计算机专业同学们,因为博主自身本科和硕士也是科班出生,所以也比较了解计算机专业的毕业设计流程以及模式&am…

竞赛选题 深度学习 opencv python 实现中国交通标志识别_1

文章目录 0 前言1 yolov5实现中国交通标志检测2.算法原理2.1 算法简介2.2网络架构2.3 关键代码 3 数据集处理3.1 VOC格式介绍3.2 将中国交通标志检测数据集CCTSDB数据转换成VOC数据格式3.3 手动标注数据集 4 模型训练5 实现效果5.1 视频效果 6 最后 0 前言 &#x1f525; 优质…

【安鸾靶场】实战渗透

文章目录 前言一、租房网 (150分)二、企业网站 (300分)三、SQL注入进阶 (550分) 前言 最近看到安鸾的靶场有些比较有意思就打了一下午&#xff0c;有一定难度。 一、租房网 (150分) http://106.15.50.112:8031/ 刚打开burp就报了thinkphp的代码执行 直接getshell flag&a…

基于SpringBoot的学生选课系统

基于SpringBoot的学生选课系统的设计与实现&#xff0c;前后端分离 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBootMyBatisVue工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 前台主页 登录界面 管理员界面 教师界面 学生界面 摘要 学生选课系统…

Javascript文件上传

什么是文件上传 文件上传包含两部分&#xff0c; 一部分是选择文件&#xff0c;包含所有相关的界面交互。一部分是网络传输&#xff0c;通过一个网络请求&#xff0c;将文件的数据携带过去&#xff0c;传递到服务器中&#xff0c;剩下的&#xff0c;在服务器中如何存储&#xf…