java配置AOP切面,用户操作记录入库

本文介绍了如何使用Mybatis-Plus创建操作日志表,引入相关依赖,创建实体类,定义Mapper接口,自定义AOP注解以及配置切面,以便在特定接口上记录用户操作。同时提到待优化的问题,关于处理文件上传下载接口时参数类型不匹配的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.创建表

CREATE TABLE `t_operate_log` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `project_type` varchar(100) DEFAULT NULL COMMENT '项目类型',
  `user_account` varchar(100) DEFAULT NULL COMMENT '操作用户账号',
  `username` varchar(100) DEFAULT '' COMMENT '操作用户名',
  `operation` varchar(200) DEFAULT '' COMMENT '操作描述',
  `method` varchar(500) DEFAULT '' COMMENT '操作方法',
  `params` text COMMENT '操作参数',
  `ip` varchar(50) DEFAULT '' COMMENT '操作IP地址',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`),
  KEY `idx_username` (`username`),
  KEY `idx_create_time` (`create_time`)
) ENGINE=InnoDB AUTO_INCREMENT=1749060808100294658 DEFAULT CHARSET=utf8mb4 COMMENT='操作日志表';

2.引入依赖

<!--       使用mybatis-plus对数据库进行操作-->
<dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.2</version>
        </dependency>
<!--        日志-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.83</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.12.0</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jul-to-slf4j</artifactId>
            <version>1.7.25</version>
            <scope>compile</scope>
        </dependency>

3.创建实体类

package com.remote.domain.pojo;

import lombok.Data;

import java.util.Date;

/**
 * @Author: majinzhong
 * @Data:2024/1/19
 */
@Data
public class TOperateLog {

    private Long id;
    private String projectType;
    private String userAccount;
    private String username;
    private String operation;
    private String method;
    private String params;
    private String ip;
    private Date createTime;

    // 省略 getter 和 setter 方法
}

4.Mapper

package com.remote.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.remote.domain.pojo.TOperateLog;
import org.apache.ibatis.annotations.Mapper;

/**
 * @Author: majinzhong
 * @Data:2024/1/19
 */
@Mapper
public interface OperateLogMapper extends BaseMapper<TOperateLog> {
}

5.自定义注解

package com.remote.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @Author: majinzhong
 * @Data:2024/1/19
 * 自定义操作日志注解
 */
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface OperateLog {
    /**
     * 操作描述,默认为空字符串
     * @return String
     */
    String value() default "";
}


6.配置aop切面

package com.remote.aop;

/**
 * @Author: majinzhong
 * @Data:2024/1/19
 */
import javax.servlet.http.HttpServletRequest;

import cn.hutool.json.JSONUtil;
import com.remote.annotation.OperateLog;
import com.remote.domain.pojo.ExperimentInfo;
import com.remote.domain.pojo.TOperateLog;
import com.remote.domain.pojo.UserInfo;
import com.remote.mapper.ExperimentInfoMapper;
import com.remote.mapper.UserInfoMapper;
import com.remote.service.OperateLogService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
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.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import java.util.Date;
import java.util.List;

@Aspect
@Component
public class OperateLogAspect {

    @Autowired
    private OperateLogService operateLog;
    @Autowired
    UserInfoMapper userInfoMapper;
    @Autowired
    ExperimentInfoMapper experimentInfoMapper;

    /**
     * 切点
     * 针对带有@OperateLog注解的方法进行切面处理
     */
    @Pointcut("@annotation(com.remote.annotation.OperateLog)")
    public void operateLogAspect() {}

    /**
     * 环绕通知
     * 在方法执行前后进行日志记录
     */
    @Around("operateLogAspect()")
    public Object operateLog(ProceedingJoinPoint joinPoint) throws Throwable {
        // 获取HttpServletRequest
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        // 获取操作的用户
        String accesstoken = request.getHeader("Accesstoken");
        String projectType=null;
        String userAccount=null;
        String username=null;

        /**
         * 添加逻辑,获取用户信息
         */

        if(!StringUtils.isEmpty(userAccount)) {
            // 获取操作方式
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            String method = signature.getDeclaringTypeName() + "." + signature.getName();
            OperateLog logAnnotation = signature.getMethod().getAnnotation(OperateLog.class);
            String operation = logAnnotation.value();

            // 获取操作参数
            JSONObject params = new JSONObject();
            Object[] args = joinPoint.getArgs();
            String[] parameterNames = signature.getParameterNames();
            for (int i = 0; i < args.length; i++) {
                params.put(parameterNames[i], JSON.toJSONString(args[i]));
            }

            // 获取IP地址
            String ip = request.getRemoteAddr();

            TOperateLog log = new TOperateLog();
            log.setProjectType(projectType);
            log.setUserAccount(userAccount);
            log.setUsername(username);
            log.setOperation(operation);
            log.setMethod(method);
            log.setParams(params.toString());
            log.setIp(ip);
            log.setCreateTime(new Date());

            operateLog.saveLog(log);
        }
        // 执行方法并记录日志
        Object result = joinPoint.proceed();

        return result;
    }
}


7.在想要记录用户操作的接口上添加@OperateLog("用户请求量增加接口")就可以了

8.执行之后数据库中的记录如下图

补充:(待优化)因为接口中有上传或者下载文件的接口,但是表中存储的入参和返回值都是字符串,所以会存在上传或者下载接口时的报错

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值