springboot项目自定义注解+Aop实现收集日志

news2024/11/28 20:42:13

一 工程结构

二 配置

2.1 配置pom

<!--spring boot的启动类 -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.16.18</version>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>

    <dependency>
      <groupId>com.baomidou</groupId>
      <artifactId>mybatis-plus-boot-starter</artifactId>
      <scope>provided </scope>
    </dependency>
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>fastjson</artifactId>
      <version>2.0.0</version>
    </dependency>

2.2 自定义枚举

1.业务枚举

package com.ljf.aopdemo.log.enums;

public enum BusinessType {
    /**
     * 其它
     */
    OTHER,

    /**
     * 新增
     */
    INSERT,

    /**
     * 修改
     */
    UPDATE,

    /**
     * 删除
     */
    DELETE,

    /**
     * 授权
     */
    ASSGIN,

    /**
     * 导出
     */
    EXPORT,

    /**
     * 导入
     */
    IMPORT,

    /**
     * 强退
     */
    FORCE,

    /**
     * 更新状态
     */
    STATUS,

    /**
     * 清空数据
     */
    CLEAN,
}

2.功能类型枚举

package com.ljf.aopdemo.log.enums;

/**
 * 操作人类别
 */
public enum OperatorType {
    /**
     * 其它
     */
    OTHER,

    /**
     * 后台用户
     */
    MANAGE,

    /**
     * 手机端用户
     */
    MOBILE
}

2.3 自定义注解

 代码

package com.ljf.aopdemo.log.aspect;


import com.alibaba.fastjson.JSON;
import com.ljf.aopdemo.log.annotation.Log;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Collection;
import java.util.Map;

@Aspect
@Component
public class LogAspect {

   // @Autowired
    //private OperLogService operLogService;

    @AfterReturning(pointcut = "@annotation(sbLog)", returning = "jsonResult")
    public void doAfterReturning(JoinPoint joinPoint, Log sbLog, Object jsonResult) {
        handleLog(joinPoint, sbLog, null, jsonResult);
    }

    protected void handleLog(final JoinPoint joinPoint, Log controllerLog, final Exception e, Object jsonResult) {
        try {
            RequestAttributes ra = RequestContextHolder.getRequestAttributes();
            ServletRequestAttributes sra = (ServletRequestAttributes) ra;
            HttpServletRequest request = sra.getRequest();

            // *========数据库日志=========*//
            // 设置方法名称
            String className = joinPoint.getTarget().getClass().getName();
            String methodName = joinPoint.getSignature().getName();
           System.out.println("calssname:"+className+" methodname:"+methodName);
        } catch (Exception exp) {
            exp.printStackTrace();
        }
    }



    /**
     * 参数拼装
     */
    private String argsArrayToString(Object[] paramsArray) {
        String params = "";
        if (paramsArray != null && paramsArray.length > 0) {
            for (Object o : paramsArray) {
                if (!StringUtils.isEmpty(o) && !isFilterObject(o)) {
                    try {
                        Object jsonObj = JSON.toJSON(o);
                        params += jsonObj.toString() + " ";
                    } catch (Exception e) {
                    }
                }
            }
        }
        return params.trim();
    }

    /**
     * 判断是否需要过滤的对象。
     *
     * @param o 对象信息。
     * @return 如果是需要过滤的对象,则返回true;否则返回false。
     */
    @SuppressWarnings("rawtypes")
    public boolean isFilterObject(final Object o) {
        Class<?> clazz = o.getClass();
        if (clazz.isArray()) {
            return clazz.getComponentType().isAssignableFrom(MultipartFile.class);
        } else if (Collection.class.isAssignableFrom(clazz)) {
            Collection collection = (Collection) o;
            for (Object value : collection) {
                return value instanceof MultipartFile;
            }
        } else if (Map.class.isAssignableFrom(clazz)) {
            Map map = (Map) o;
            for (Object value : map.entrySet()) {
                Map.Entry entry = (Map.Entry) value;
                return entry.getValue() instanceof MultipartFile;
            }
        }
        return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse
                || o instanceof BindingResult;
    }
}

2.4 触发收集日志的配置

@RestController
public class RoleController {
    @GetMapping("/testjson")
    @Log(title = "角色管理testjson",businessType = BusinessType.INSERT)
    public Object testjson(){
        Map<String,String> map = new HashMap<>();
        return "ok成功" ;
    }
}

2.5 测试验证

1.页面访问

2.日志打印

 

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Sentinel的线程隔离和熔断降级

上一节整理了Sentinel的限流&#xff0c;限流可以降低微服务的负载&#xff0c;避免因为高并发而故障&#xff0c;进而传递给其他相关服务而引发服务雪崩。以上仅为避免服务故障&#xff0c;而当某个服务真正故障时&#xff0c;如何处理才能防止服务雪崩&#xff1f; ⇒ Sentin…

二十一、vm 适配

目录&#xff1a; 1. 基础准备 2. 详解 一、基础准备 目的&#xff1a;前面我们通过0.1333vm x 对应的设计图像素&#xff0c;找到vm值&#xff0c;这个方法不准确&#xff0c;且操作复杂&#xff0c;有没有什么优化方法呢&#xff1f; 解决&#xff1a;vw的适配&#xff08;在…

Bard:一个可以描述图像的人工智能

Bard 是一个大型语言模型&#xff0c;可以对各种提示和问题进行交流和生成类似人类的文本。它接受了大量的文字和代码训练&#xff0c;可以生成文本、翻译语言、编写不同类型的创意内容&#xff0c;并以信息丰富的方式回答你的问题。 Bard 还可以识别图像。它可以识别图像中的…

python编程语言之进阶语法

迭代器 可迭代对象 讲迭代器之前&#xff0c;我们先了解一个概念&#xff1a;可迭代对象(Iterable)。 那么什么是可迭代&#xff1f;什么是对象&#xff1f; 迭代(Iteration)&#xff0c;是指通过遍历获取某容器内所有元素&#xff0c;特指遍历获取这个动作。 可迭代 (iter…

EasyCVR录像阈值配置未生效,是什么原因?

有用户反馈&#xff0c;在平台中设置了录像阈值不生效&#xff0c;导致磁盘爆满。针对该反馈&#xff0c;我们立即进行了排查。 EasyCVR基于云边端一体化架构&#xff0c;可支持多协议、多类型设备接入&#xff0c;在视频能力上&#xff0c;平台可实现视频直播、录像、回放、检…

用C语言对学生成绩进行排序(归并排序与基数排序)

一.前言 我们内部排序已经学了插入排序&#xff08;直接插入排序、折半插入排序、希尔排序&#xff09;&#xff0c;交换排序&#xff08;冒泡排序、快速排序&#xff09;&#xff0c;选择排序&#xff08;简单选择排序、堆排序&#xff09;&#xff0c;这些都属于内部排序&…

ShardingSphere分库分表实战之绑定表

&#x1f680; ShardingSphere &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&…

DAY48:动态规划(十二)完全平方数(类似零钱兑换)+单词拆分(注意背包思路!)

文章目录 279.完全平方数&#xff08;类似零钱兑换&#xff09;思路DP数组含义递推公式初始化遍历顺序 最开始的写法&#xff1a;有1个用例没过修改完整版总结 139.单词拆分&#xff08;递推公式注意&#xff09;思路1&#xff1a;遍历单词分割点DP数组含义递推公式初始化遍历顺…

基于Java+SpringBoot+Vue前后端分离旅游网站详细设计和实现

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

导航菜单 改变背景色

直接参考官网上的案例即可 //active-text-color 点击时修改字体颜色 // background-color 背景色 // text-color 字体颜色<el-menudefault-active"2"class"el-menu-vertical-demo"open"handleOpen"close"handleClose"background…

Java:控制流程 + 数组 详解(原理 + 用法 + 例子)

目录 控制流程块作用域if 条件语句for while 循环switch 多重选择break continue 中断控制流程语句 大数值数组多维数组字符串类型数组Array.sort() 数组排序for each 循环 控制流程 块作用域 块&#xff08;即复合语句&#xff09;是指由一对大括号{}括起来的若干条简单的 Ja…

ARP解析MAC地址的全过程(ARP的工作机制)

目录 ARP解析MAC地址的过程&#xff1a; 源码等资料获取方法 以太网环境下&#xff0c;同一个网段的主机之间需要互相知道对方的MAC地址&#xff0c;才能访问。 TCP/IP协议栈从上层到下层的封装过程中&#xff0c;第三层封装需要知道目的IP&#xff0c;第二层封装需要知道目…

Linux下安装Mysql (CentOS 7) 详解

文章目录 前言环境检查查看是否安装MySql查看系统版本 源安装安装mysql的yum源官网下载从windows上传到linuxrz命令 方法2&#xff1a; 安装Mysql常见错误密钥问题安装后查看mysql是否可以工作查看是否安装成功启动服务 登录mysql配置文件方法&#xff08;免密码&#xff09; 使…

linux 安装 cuda

需求&#xff1a; inux 下安装 cuda 进程&#xff1a; 先查看一下系统版本 uname -a查看能支持什么版本的cudacuda toolkit 下载 wget https://developer.download.nvidia.com/compute/cuda/11.1.0/local_installers/cuda_11.1.0_455.23.05_linux.run sudo sh cuda_11.1.0_4…

MySql冷门但是很有用的语句

目录 1 查看当前的所有执行的进程 查看简略信息 查看详细信息 2 在所有数据库中查询包含某个字段的表 精确 模糊 1 查看当前的所有执行的进程 查看简略信息 show processlist 查看详细信息 show full processlist 终止进程 kill id 2 在所有数据库中查询包含某个字段…

gurobi安装vs配置gurobi

gurobi安装&vs配置gurobi 1、注册账号并登录 2、下载gurobi optimizer 3、获取license:User Portal (gurobi.com) online course可以免ip验证。 4、GENERATE NOW会生成&#xff0c;打开cmd进入gurobi安装路径&#xff08;如F:\gurobi1001\win64\bin>&#xff09;&am…

分布式事务 Seata

分布式事务 Seata 事务介绍分布式理论Seata 介绍Seata 部署与集成Seata TC Server 部署微服务集成 Seata XA 模式AT 模式AT 模式执行过程读写隔离写隔离读隔离 实现 AT 模式 TCC 模式TCC 模式介绍实现 TCC 模式 Saga 模式Seata 四种模式对比 事务介绍 事务&#xff08;Transac…

分布式光伏监控系统运维系统实时查看数据分布式光伏电站监控管理

光伏电站是一种利用太阳能发电的设施&#xff0c;随着人们对可再生能源的需求不断增加&#xff0c;光伏电站的建设也越来越普遍。但是&#xff0c;光伏电站的运营和管理需要高质量的监控系统来确保其正常运行。本文将介绍光伏电站监控系统的组成及其原理。 详细软件具体需求可…

php连接上mysql数据库该的配置方法

用mysql官方的管理工具workbench&#xff1a; 打开导出界面后&#xff0c;下一步&#xff0c;选择csv格式&#xff0c;导出后excel就能打开了 如果你需要在程序代码中导出&#xff0c;需要找到对应代码的excel处理库。 如php 的 phpExcel( 最新版已更名为 phpoffice/phpspread…

vue3组件中使用live2d看板娘(官方包形式)

文章目录 先看最终效果吧关于官方包下载使用 vue3中调整使用基础使用关于样式调整 vue中Html主页调试&#xff08;备用调试方案&#xff09; 先看最终效果吧 看着还可以&#xff0c;其实还有很多问题没解决&#xff0c;因为是完全靠js渲染&#xff0c;实际上这个live2d的canvas…