SpringBoot利用AOP实现一个日志管理详解

2023-05-16 0 611

目录

1. 需求

目前有这么个问题,有两个系统CSP和OMS,这俩系统共用的是同一套日志操作:Log;目前想区分下这俩系统的日志操作,那没办法了,只能重写一份Log的日志操作;

你也可以参照若依框架的日志系统实现。

2. 新建一张日志表

sys_oper_csp_log

/*
 Navicat Premium Data Transfer

 Source Server         : jp-csc-admin
 Source Server Type    : MySQL
 Source Server Version : 50728
 Source Host           : rm-uf6miy84gu8u433x9.mysql.rds.aliyuncs.com:3306
 Source Schema         : jp_oms

 Target Server Type    : MySQL
 Target Server Version : 50728
 File Encoding         : 65001

 Date: 08/09/2022 09:21:45
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for sys_oper_csp_log
-- ----------------------------
DROP TABLE IF EXISTS `sys_oper_csp_log`;
CREATE TABLE `sys_oper_csp_log`  (
  `oper_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT \'日志主键\',
  `title` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT \'\' COMMENT \'模块标题\',
  `business_type` int(2) NULL DEFAULT 0 COMMENT \'业务类型(0=其它,1=新增,2=修改,3=删除,4=授权,5=导出,6=导入,7=强退,8=生成代码,9=清空数据)\',
  `method` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT \'\' COMMENT \'方法名称\',
  `request_method` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT \'\' COMMENT \'请求方式\',
  `operator_type` int(1) NULL DEFAULT 0 COMMENT \'操作类别(0其它 1后台用户 2手机端用户)\',
  `oper_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT \'\' COMMENT \'操作人员\',
  `dept_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT \'\' COMMENT \'部门名称\',
  `oper_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT \'\' COMMENT \'请求URL\',
  `oper_ip` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT \'\' COMMENT \'主机地址\',
  `oper_location` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT \'\' COMMENT \'操作地点\',
  `oper_param` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT \'\' COMMENT \'请求参数\',
  `json_result` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT \'返回参数\',
  `status` int(1) NULL DEFAULT 0 COMMENT \'操作状态(0正常 1异常)\',
  `error_msg` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT \'\' COMMENT \'错误消息\',
  `oper_time` datetime NULL DEFAULT NULL COMMENT \'操作时间\',
  PRIMARY KEY (`oper_id`) USING BTREE,
  INDEX `idx_time`(`oper_time`, `title`, `oper_name`) USING BTREE
) ENGINE = InnoD CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = \'CSP系统操作日志记录\';

3. 写相应的Controller

package com.juepeiscm.csp.controller.csplog;

import com.juepeiscm.admin.api.domain.SysOperLog;
import com.juepeiscm.common.core.controller.BaseController;
import com.juepeiscm.common.core.domain.AjaxResult;
import com.juepeiscm.common.core.page.TableDataInfo;
import com.juepeiscm.common.enums.BusinessType;
import com.juepeiscm.common.utils.poi.ExcelUtil;
import com.juepeiscm.csp.annotation.CspLog;
import com.juepeiscm.csp.domain.csplog.SysOperCspLog;
import com.juepeiscm.csp.service.csplog.ISysOperCspLogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 操作CSP系统日志
 * @Author: py.sun
 * @Date: 2022/9/7 14:51
 */
@RestController
@RequestMapping({\"/csplog/opercsplog\"})
public class SysOperCsplogController extends BaseController {
    @Autowired
    private ISysOperCspLogService operCspLogService;

    public SysOperCsplogController() {
    }

    /**
     * 查询操作日志列表
     * @param sysOperCspLog
     * @return
     */
    @PreAuthorize(\"@ss.hasPermi(\'monitor:operlog:list\')\")
    @GetMapping({\"/list\"})
    public TableDataInfo list(SysOperCspLog sysOperCspLog) {
        this.startPage();
        List<SysOperCspLog> list = this.operCspLogService.selectOperLogList(sysOperCspLog);
        return this.getDataTable(list);
    }

    /**
     * 查询系统模块的分类
     * @param
     * @return
     */
    @GetMapping({\"/listTitle\"})
    public TableDataInfo listTitle() {
        this.startPage();
        List<String> list = this.operCspLogService.selectOperLogListTitle();
        return this.getDataTable(list);
    }

    @CspLog(
            title = \"导出CSP系统日志\",
            businessType = BusinessType.EXPORT
    )
    @PreAuthorize(\"@ss.hasPermi(\'monitor:operlog:export\')\")
    @GetMapping({\"/export\"})
    public AjaxResult export(SysOperCspLog operLog) {
        List<SysOperCspLog> list = this.operCspLogService.selectOperLogList(operLog);
        ExcelUtil<SysOperCspLog> util = new ExcelUtil(SysOperLog.class);
        return util.exportExcel(list, \"操作CSP系统日志\");
    }

    @CspLog(
            title = \"操作CSP系统日志\",
            businessType = BusinessType.DELETE
    )
    @PreAuthorize(\"@ss.hasPermi(\'monitor:operlog:remove\')\")
    @DeleteMapping({\"/{operIds}\"})
    public AjaxResult remove(@PathVariable Long[] operIds) {
        return this.toAjax(this.operCspLogService.deleteOperLogByIds(operIds));
    }

    @CspLog(
            title = \"清除CSP系统日志\",
            businessType = BusinessType.CLEAN
    )
    @PreAuthorize(\"@ss.hasPermi(\'monitor:operlog:remove\')\")
    @DeleteMapping({\"/clean\"})
    public AjaxResult clean() {
        this.operCspLogService.cleanOperLog();
        return AjaxResult.success();
    }


}

4.Service接口

package com.juepeiscm.csp.service.csplog;

import com.juepeiscm.admin.api.domain.SysOperLog;
import com.juepeiscm.csp.domain.csplog.SysOperCspLog;

import java.util.List;

/**
 * @Author: py.sun
 * @Date: 2022/9/7 15:02
 */
public interface ISysOperCspLogService {
    void insertOperlog(SysOperCspLog var1);

    List<SysOperCspLog> selectOperLogList(SysOperCspLog var1);

    List<String> selectOperLogListTitle();

    int deleteOperLogByIds(Long[] var1);

    SysOperLog selectOperLogById(Long var1);

    void cleanOperLog();
}

5.Service实现

package com.juepeiscm.csp.service.impl.csplog;

import com.juepeiscm.admin.api.domain.SysOperLog;
import com.juepeiscm.common.core.domain.AjaxResult;
import com.juepeiscm.common.core.domain.entity.SysDept;
import com.juepeiscm.common.core.domain.entity.SysUser;
import com.juepeiscm.common.core.domain.model.LoginUser;
import com.juepeiscm.common.exception.CustomException;
import com.juepeiscm.common.utils.SecurityUtils;
import com.juepeiscm.common.utils.ServletUtils;
import com.juepeiscm.common.utils.StringUtils;
import com.juepeiscm.csp.domain.csplog.SysOperCspLog;
import com.juepeiscm.csp.mapper.csplog.SysOperCspLogMapper;
import com.juepeiscm.csp.service.csplog.ISysOperCspLogService;
import com.juepeiscm.framework.web.service.TokenService;
import com.juepeiscm.uam.service.ISysDeptService;
import com.juepeiscm.uam.version.UamVersion;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @Author: py.sun
 * @Date: 2022/9/7 15:03
 */
@Service
public class SysOperCspLogServiceImpl implements ISysOperCspLogService {
    @Autowired
    private SysOperCspLogMapper operLogMapper;

    @Autowired
    private TokenService tokenService;

    @Reference(version = UamVersion.idV)
    public ISysDeptService deptService;

    @Override
    public void insertOperlog(SysOperCspLog sysOperCspLog) {
        try {
            this.operLogMapper.insertOperlog(sysOperCspLog);
        } catch (Exception e) {
            e.printStackTrace();
            throw new CustomException(\"CSP系统日志插入失败,请联系管理员!!!\");
        }

    }

    @Override
    public List<SysOperCspLog> selectOperLogList(SysOperCspLog sysOperCspLog) {
        return this.operLogMapper.selectOperLogList(sysOperCspLog);
    }

    @Override
    public List<String> selectOperLogListTitle() {
        return this.operLogMapper.selectOperLogListTitle();
    }

    @Override
    public int deleteOperLogByIds(Long[] operIds) {
        return this.operLogMapper.deleteOperLogByIds(operIds);
    }

    @Override
    public SysOperLog selectOperLogById(Long operId) {
        return this.operLogMapper.selectOperLogById(operId);
    }

    @Override
    public void cleanOperLog() {
        this.operLogMapper.cleanOperLog();
    }
}

6.Mapper接口

package com.juepeiscm.csp.mapper.csplog;

import com.juepeiscm.admin.api.domain.SysOperLog;
import com.juepeiscm.csp.domain.csplog.SysOperCspLog;

import java.util.List;

/**
 * @Author: py.sun
 * @Date: 2022/9/7 15:06
 */
public interface SysOperCspLogMapper {

    void insertOperlog(SysOperCspLog var1);

    List<SysOperCspLog> selectOperLogList(SysOperCspLog sysOperCspLog);

    List<String> selectOperLogListTitle();

    int deleteOperLogByIds(Long[] var1);

    SysOperLog selectOperLogById(Long var1);

    void cleanOperLog();
}

7.Mapper.xml(我用的是Mybatis)

<?xml version=\"1.0\" encoding=\"UTF-8\" ?>
<!DOCTYPE mapper
        PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\"
        \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">
<mapper namespace=\"com.juepeiscm.csp.mapper.csplog.SysOperCspLogMapper\">

    <resultMap type=\"SysOperCspLog\" id=\"SysOperLogResult\">
        <id     property=\"operId\"         column=\"oper_id\"        />
        <result property=\"title\"          column=\"title\"          />
        <result property=\"businessType\"   column=\"business_type\"  />
        <result property=\"method\"         column=\"method\"         />
        <result property=\"requestMethod\"  column=\"request_method\" />
        <result property=\"operatorType\"   column=\"operator_type\"  />
        <result property=\"operName\"       column=\"oper_name\"      />
        <result property=\"deptName\"       column=\"dept_name\"      />
        <result property=\"operUrl\"        column=\"oper_url\"       />
        <result property=\"operIp\"         column=\"oper_ip\"        />
        <result property=\"operLocation\"   column=\"oper_location\"  />
        <result property=\"operParam\"      column=\"oper_param\"     />
        <result property=\"jsonResult\"     column=\"json_result\"    />
        <result property=\"status\"         column=\"status\"         />
        <result property=\"errorMsg\"       column=\"error_msg\"      />
        <result property=\"operTime\"       column=\"oper_time\"      />
    </resultMap>

    <sql id=\"selectOperLogVo\">
        select oper_id, title, business_type, method, request_method, operator_type, oper_name, dept_name, oper_url, oper_ip, oper_location, oper_param, json_result, status, error_msg, oper_time
        from sys_oper_csp_log
    </sql>

    <insert id=\"insertOperlog\" parameterType=\"SysOperCspLog\">
        insert into sys_oper_csp_log(title, business_type, method, request_method, operator_type, oper_name, dept_name, oper_url, oper_ip, oper_location, oper_param, json_result, status, error_msg, oper_time)
        values (#{title}, #{businessType}, #{method}, #{requestMethod}, #{operatorType}, #{operName}, #{deptName}, #{operUrl}, #{operIp}, #{operLocation}, #{operParam}, #{jsonResult}, #{status}, #{errorMsg}, sysdate())
    </insert>

    <select id=\"selectOperLogList\" parameterType=\"SysOperCspLog\" resultMap=\"SysOperLogResult\">
        <include refid=\"selectOperLogVo\"/>
        <where>
            <if test=\"title != null and title != \'\'\">
                AND title like concat(\'%\', #{title}, \'%\')
            </if>
            <if test=\"businessType != null and businessType != \'\'\">
                AND business_type = #{businessType}
            </if>
            <if test=\"businessTypes != null and businessTypes.length > 0\">
                AND business_type in
                <foreach collection=\"businessTypes\" item=\"businessType\" open=\"(\" separator=\",\" close=\")\">
                    #{businessType}
                </foreach>
            </if>
            <if test=\"status != null\">
                AND status = #{status}
            </if>
            <if test=\"operName != null and operName != \'\'\">
                AND oper_name like concat(\'%\', #{operName}, \'%\')
            </if>
            <if test=\"params.beginTime != null and params.beginTime != \'\'\"><!-- 开始时间检索 -->
                and date_format(oper_time,\'%y%m%d\') &gt;= date_format(#{params.beginTime},\'%y%m%d\')
            </if>
            <if test=\"params.endTime != null and params.endTime != \'\'\"><!-- 结束时间检索 -->
                and date_format(oper_time,\'%y%m%d\') &lt;= date_format(#{params.endTime},\'%y%m%d\')
            </if>
        </where>
        order by oper_id desc
    </select>

    <delete id=\"deleteOperLogByIds\" parameterType=\"Long\">
        delete from sys_oper_csp_log where oper_id in
        <foreach collection=\"array\" item=\"operId\" open=\"(\" separator=\",\" close=\")\">
            #{operId}
        </foreach>
    </delete>

    <select id=\"selectOperLogById\" parameterType=\"Long\" resultMap=\"SysOperLogResult\">
        <include refid=\"selectOperLogVo\"/>
        where oper_id = #{operId}
    </select>

    <select id=\"selectOperLogListTitle\" resultType=\"java.lang.String\">
        select distinct(title)  from sys_oper_csp_log
    </select>

    <update id=\"cleanOperLog\">
        truncate table sys_oper_csp_log
    </update>

</mapper>

8.CspLog

定义一个日志管理的名称:CspLog

package com.juepeiscm.csp.annotation;

import com.juepeiscm.common.enums.BusinessType;
import com.juepeiscm.common.enums.OperatorType;

import java.lang.annotation.*;

/**
 * CSP系统的日志管理
 * @Author: py.sun
 * @Date: 2022/9/7 14:42
 * @Target表示注解可以使用到哪些地方,可以是类,方法,或者是属性上,定义在ElementType枚举中:
 * @Retention作用是定义被它所注解的注解保留多久,一共有三种策略,定义在RetentionPolicy枚举中:
 *
 * 我们的@CspLog注解,可以作用在方法和参数上,将由编译器记录在类文件中,并在运行时由VM保留,因此可以反射性地读取。该注解是通过AOP进行解析的
 */
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CspLog {
    /**
     * 模块
     * @return
     */
    String title() default \"\";

    /**
     * 功能
     * @return
     */
    BusinessType businessType() default BusinessType.OTHER;

    /**
     * 操作人类别
     * @return
     */
    OperatorType operatorType() default OperatorType.MANAGE;

    /**
     * 是否保存请求的参数
     * @return
     */
    boolean isSaveRequestData() default true;
}

9.实体类SysOperCspLog

package com.juepeiscm.csp.domain.csplog;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.juepeiscm.common.annotation.Excel;
import com.juepeiscm.common.core.domain.BaseEntity;

import java.util.Date;

/**
 * @Author: py.sun
 * @Date: 2022/9/7 15:04
 */
public class SysOperCspLog extends BaseEntity {
    private static final long serialVersionUID = 1L;
    @Excel(
            name = \"操作序号\",
            cellType = Excel.ColumnType.NUMERIC
    )
    private Long operId;
    @Excel(
            name = \"操作模块\"
    )
    private String title;
    @Excel(
            name = \"业务类型\",
            readConverterExp = \"0=其它,1=新增,2=修改,3=删除,4=授权,5=导出,6=导入,7=强退,8=生成代码,9=清空数据\"
    )
    private Integer businessType;
    private Integer[] businessTypes;
    @Excel(
            name = \"请求方法\"
    )
    private String method;
    @Excel(
            name = \"请求方式\"
    )
    private String requestMethod;
    @Excel(
            name = \"操作类别\",
            readConverterExp = \"0=其它,1=后台用户,2=手机端用户\"
    )
    private Integer operatorType;
    @Excel(
            name = \"操作人员\"
    )
    private String operName;
    @Excel(
            name = \"部门名称\"
    )
    private String deptName;
    @Excel(
            name = \"请求地址\"
    )
    private String operUrl;
    @Excel(
            name = \"操作地址\"
    )
    private String operIp;
    @Excel(
            name = \"操作地点\"
    )
    private String operLocation;
    @Excel(
            name = \"请求参数\"
    )
    private String operParam;
    @Excel(
            name = \"返回参数\"
    )
    private String jsonResult;
    @Excel(
            name = \"状态\",
            readConverterExp = \"0=正常,1=异常\"
    )
    private Integer status;
    @Excel(
            name = \"错误消息\"
    )
    private String errorMsg;
    @JsonFormat(
            pattern = \"yyyy-MM-dd HH:mm:ss\"
    )
    @Excel(
            name = \"操作时间\",
            width = 30.0D,
            dateFormat = \"yyyy-MM-dd HH:mm:ss\"
    )
    private Date operTime;

    public SysOperCspLog() {
    }

    public Long getOperId() {
        return this.operId;
    }

    public void setOperId(Long operId) {
        this.operId = operId;
    }

    public String getTitle() {
        return this.title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public Integer getBusinessType() {
        return this.businessType;
    }

    public void setBusinessType(Integer businessType) {
        this.businessType = businessType;
    }

    public Integer[] getBusinessTypes() {
        return this.businessTypes;
    }

    public void setBusinessTypes(Integer[] businessTypes) {
        this.businessTypes = businessTypes;
    }

    public String getMethod() {
        return this.method;
    }

    public void setMethod(String method) {
        this.method = method;
    }

    public String getRequestMethod() {
        return this.requestMethod;
    }

    public void setRequestMethod(String requestMethod) {
        this.requestMethod = requestMethod;
    }

    public Integer getOperatorType() {
        return this.operatorType;
    }

    public void setOperatorType(Integer operatorType) {
        this.operatorType = operatorType;
    }

    public String getOperName() {
        return this.operName;
    }

    public void setOperName(String operName) {
        this.operName = operName;
    }

    public String getDeptName() {
        return this.deptName;
    }

    public void setDeptName(String deptName) {
        this.deptName = deptName;
    }

    public String getOperUrl() {
        return this.operUrl;
    }

    public void setOperUrl(String operUrl) {
        this.operUrl = operUrl;
    }

    public String getOperIp() {
        return this.operIp;
    }

    public void setOperIp(String operIp) {
        this.operIp = operIp;
    }

    public String getOperLocation() {
        return this.operLocation;
    }

    public void setOperLocation(String operLocation) {
        this.operLocation = operLocation;
    }

    public String getOperParam() {
        return this.operParam;
    }

    public void setOperParam(String operParam) {
        this.operParam = operParam;
    }

    public String getJsonResult() {
        return this.jsonResult;
    }

    public void setJsonResult(String jsonResult) {
        this.jsonResult = jsonResult;
    }

    public Integer getStatus() {
        return this.status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }

    public String getErrorMsg() {
        return this.errorMsg;
    }

    public void setErrorMsg(String errorMsg) {
        this.errorMsg = errorMsg;
    }

    public Date getOperTime() {
        return this.operTime;
    }

    public void setOperTime(Date operTime) {
        this.operTime = operTime;
    }
}

10. 定义日志管理的切面

大家一定要记住哈,所有针对实体的SysOperCspLog赋值操作必须在这里main执行。

package com.juepeiscm.csp.controller.utils;

import com.alibaba.fastjson.JSON;
import com.juepeiscm.common.core.domain.entity.SysDept;
import com.juepeiscm.common.core.domain.model.LoginUser;
import com.juepeiscm.common.enums.BusinessStatus;
import com.juepeiscm.common.enums.HttpMethod;
import com.juepeiscm.common.utils.ServletUtils;
import com.juepeiscm.common.utils.StringUtils;
import com.juepeiscm.common.utils.ip.IpUtils;
import com.juepeiscm.common.utils.spring.SpringUtils;
import com.juepeiscm.csp.annotation.CspLog;
import com.juepeiscm.csp.domain.csplog.SysOperCspLog;
import com.juepeiscm.framework.aspectj.LogAspect;
import com.juepeiscm.framework.manager.AsyncManager;
import com.juepeiscm.framework.web.service.TokenService;
import com.juepeiscm.uam.service.ISysDeptService;
import com.juepeiscm.uam.version.UamVersion;
import org.apache.dubbo.config.annotation.Reference;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindingResult;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.HandlerMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;

/**
 * @Author: py.sun
 * @Date: 2022/9/7 16:31
 * 操作日志记录处理
 */
@Aspect
@Component
public class CspLogAspect {
    private static final Logger log = LoggerFactory.getLogger(CspLog.class);

    @Reference(version = UamVersion.idV)
    public ISysDeptService deptService;

    public CspLogAspect() {
    }

    //把@CspLog配置为切入点。   配置织入点
    @Pointcut(\"@annotation(com.juepeiscm.csp.annotation.CspLog)\")
    public void logPointCut() {
    }

    //拦截异常操作
    // 处理完请求后执行该方法。也就是用@CspLog注解的方法,执行完后,调用handleLog方法,处理返回结果。
    @AfterReturning(
            pointcut = \"logPointCut()\",
            returning = \"jsonResult\"
    )
    public void doAfterReturning(JoinPoint joinPoint, Object jsonResult) {
        this.handleLog(joinPoint, (Exception)null, jsonResult);
    }

    @AfterThrowing(
            value = \"logPointCut()\",
            throwing = \"e\"
    )
    public void doAfterThrowing(JoinPoint joinPoint, Exception e) {
        this.handleLog(joinPoint, e, (Object)null);
    }

    // 如果函数抛出了异常,也是执行handleLog方法,不过和正常返回的参数不一样,此处是为了处理异常。
    protected void handleLog(JoinPoint joinPoint, Exception e, Object jsonResult) {
        try {
            // 获得注解
            CspLog controllerLog = this.getAnnotationLog(joinPoint);
            if (controllerLog == null) {
                return;
            }

            // 获取当前的用户
            LoginUser loginUser = ((TokenService) SpringUtils.getBean(TokenService.class)).getLoginUser(ServletUtils.getRequest());
            // *========数据库日志=========*//
            SysOperCspLog operLog = new SysOperCspLog();
            operLog.setStatus(BusinessStatus.SUCCESS.ordinal());
            // 请求的地址
            String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
            operLog.setOperIp(ip);
            // 返回参数
            operLog.setJsonResult(JSON.toJSONString(jsonResult));
            operLog.setOperUrl(ServletUtils.getRequest().getRequestURI());
            if (loginUser != null) {
                operLog.setOperName(loginUser.getUsername());
            }

            // 获取当前登录用户的部门名称
            SysDept sysDept = deptService.selectDeptIdByUserIdAndAppId(loginUser.getUser().getUserId(), \"oms\");
            if(sysDept != null && StringUtils.isNotEmpty(sysDept.getDeptName())){
                    operLog.setDeptName(sysDept.getDeptName());
            }

            if (e != null) {
                operLog.setStatus(BusinessStatus.FAIL.ordinal());
                operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000));
            }

            // 设置方法名称
            String className = joinPoint.getTarget().getClass().getName();
            String methodName = joinPoint.getSignature().getName();
            operLog.setMethod(className + \".\" + methodName + \"()\");
            // 设置请求方式
            operLog.setRequestMethod(ServletUtils.getRequest().getMethod());
            // 处理设置注解上的参数
            this.getControllerMethodDescription(joinPoint, controllerLog, operLog);
            // 保存数据库
            AsyncManager.me().execute(AsyncFactoryCsp.recordOper(operLog));
        } catch (Exception var10) {
            // 记录本地异常日志
            log.error(\"==前置通知异常==\");
            log.error(\"异常信息:{}\", var10.getMessage());
            var10.printStackTrace();
        }

    }

    public void getControllerMethodDescription(JoinPoint joinPoint, CspLog log, SysOperCspLog operLog) throws Exception {
        operLog.setBusinessType(log.businessType().ordinal());
        operLog.setTitle(log.title());
        operLog.setOperatorType(log.operatorType().ordinal());
        if (log.isSaveRequestData()) {
            this.setRequestValue(joinPoint, operLog);
        }

    }

    private void setRequestValue(JoinPoint joinPoint, SysOperCspLog operLog) throws Exception {
        String requestMethod = operLog.getRequestMethod();
        if (!HttpMethod.PUT.name().equals(requestMethod) && !HttpMethod.POST.name().equals(requestMethod)) {
            Map<?, ?> paramsMap = (Map)ServletUtils.getRequest().getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
            operLog.setOperParam(StringUtils.substring(paramsMap.toString(), 0, 2000));
        } else {
            String params = this.argsArrayToString(joinPoint.getArgs());
            operLog.setOperParam(StringUtils.substring(params, 0, 2000));
        }

    }

    private CspLog getAnnotationLog(JoinPoint joinPoint) throws Exception {
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature)signature;
        Method method = methodSignature.getMethod();
        return method != null ? (CspLog)method.getAnnotation(CspLog.class) : null;
    }

    private String argsArrayToString(Object[] paramsArray) {
        String params = \"\";
        if (paramsArray != null && paramsArray.length > 0) {
            for(int i = 0; i < paramsArray.length; ++i) {
                if (StringUtils.isNotNull(paramsArray[i]) && !this.isFilterObject(paramsArray[i])) {
                    Object jsonObj = JSON.toJSON(paramsArray[i]);
                    params = params + jsonObj.toString() + \" \";
                }
            }
        }

        return params.trim();
    }

    public boolean isFilterObject(Object o) {
        Class<?> clazz = o.getClass();
        if (clazz.isArray()) {
            return clazz.getComponentType().isAssignableFrom(MultipartFile.class);
        } else {
            Iterator iter;
            if (Collection.class.isAssignableFrom(clazz)) {
                Collection collection = (Collection)o;
                iter = collection.iterator();
                if (iter.hasNext()) {
                    return iter.next() instanceof MultipartFile;
                }
            } else if (Map.class.isAssignableFrom(clazz)) {
                Map map = (Map)o;
                iter = map.entrySet().iterator();
                if (iter.hasNext()) {
                    Map.Entry entry = (Map.Entry)iter.next();
                    return entry.getValue() instanceof MultipartFile;
                }
            }

            return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse || o instanceof BindingResult;
        }
    }
}

11.AsyncFactoryCsp

package com.juepeiscm.csp.controller.utils;
import com.juepeiscm.common.utils.ip.AddressUtils;
import com.juepeiscm.common.utils.spring.SpringUtils;
import com.juepeiscm.csp.domain.csplog.SysOperCspLog;
import com.juepeiscm.csp.service.csplog.ISysOperCspLogService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.TimerTask;

/**
 * @Author: py.sun
 * @Date: 2022/9/7 16:47
 */
public class AsyncFactoryCsp {
    private static final Logger sys_user_logger = LoggerFactory.getLogger(\"sys-user\");

    public AsyncFactoryCsp() {
    }

    public static TimerTask recordOper(final SysOperCspLog operLog) {
        return new TimerTask() {
            public void run() {
                operLog.setOperLocation(AddressUtils.getRealAddressByIP(operLog.getOperIp()));
                ((ISysOperCspLogService) SpringUtils.getBean(ISysOperCspLogService.class)).insertOperlog(operLog);
            }
        };
    }
}

12. 写一个Controller的Demo来执行一条日志试试

在这里插入代码片package com.juepeiscm.csp.controller.order;

在这里插入代码片package com.juepeiscm.csp.controller.order;

import com.alibaba.fastjson.JSON;
import com.juepeiscm.admin.api.service.ISysDictDataService;
import com.juepeiscm.common.annotation.RepeatSubmit;
import com.juepeiscm.common.core.controller.BaseController;
import com.juepeiscm.common.core.domain.AjaxResult;
import com.juepeiscm.common.core.domain.entity.SysDictData;
import com.juepeiscm.common.core.page.TableDataInfo;
import com.juepeiscm.common.enums.BusinessType;
import com.juepeiscm.common.exception.BaseException;
import com.juepeiscm.common.utils.StringUtils;
import com.juepeiscm.common.utils.poi.ExcelUtil;
import com.juepeiscm.csp.annotation.CspLog;
import com.juepeiscm.csp.domain.order.CspGodownEntry;
import com.juepeiscm.csp.domain.order.CspGodownEntryDetails;
import com.juepeiscm.csp.service.common.MenuLogService;
import com.juepeiscm.csp.service.data.ICspGoodsdataService;
import com.juepeiscm.csp.service.order.ICspGodownEntryService;
import com.juepeiscm.csp.vo.GodownEntryExcel;
import com.juepeiscm.csp.vo.GoodsDataForGodownEntryDetails;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 入库订单Controller
 *
 * @author juepeiscm
 * @date 2021-07-23
 */
@Api(tags = \"入库订单接口\")
@RestController
@RequestMapping(\"/order/godownEntry\")
public class CspGodownEntryController extends BaseController {

    private static final Logger logger = LoggerFactory.getLogger(CspGodownEntryController.class);

    @Autowired
    private ICspGodownEntryService cspGodownEntryService;
    @Autowired
    private ICspGoodsdataService goodsDataService;
    @Autowired
    private MenuLogService menuLogService;
    @Autowired
    private ISysDictDataService sysDictDataService;

    /**
     * 新增入库订单Demo
     */
    @PreAuthorize(\"@ss.hasPermi(\'order:godownEntry:add\')\")
    @ApiOperation(value = \"新增入库订单\")
    @CspLog(title = \"入库订单demo4\", businessType = BusinessType.INSERT)
    @PostMapping(\"/addOrder\")
    @RepeatSubmit
    public AjaxResult addDemo(@RequestBody @Valid CspGodownEntry godownEntry) {
        try {
            return toAjax(cspGodownEntryService.insertOmsGodownEntry(godownEntry));
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error(\"新增失败,请联系管理员\");
        }
    }
}

测试下,看看数据库内容

SpringBoot利用AOP实现一个日志管理详解

资源下载此资源下载价格为1小猪币,终身VIP免费,请先
由于本站资源来源于互联网,以研究交流为目的,所有仅供大家参考、学习,不存在任何商业目的与商业用途,如资源存在BUG以及其他任何问题,请自行解决,本站不提供技术服务! 由于资源为虚拟可复制性,下载后不予退积分和退款,谢谢您的支持!如遇到失效或错误的下载链接请联系客服QQ:442469558

:本文采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可, 转载请附上原文出处链接。
1、本站提供的源码不保证资源的完整性以及安全性,不附带任何技术服务!
2、本站提供的模板、软件工具等其他资源,均不包含技术服务,请大家谅解!
3、本站提供的资源仅供下载者参考学习,请勿用于任何商业用途,请24小时内删除!
4、如需商用,请购买正版,由于未及时购买正版发生的侵权行为,与本站无关。
5、本站部分资源存放于百度网盘或其他网盘中,请提前注册好百度网盘账号,下载安装百度网盘客户端或其他网盘客户端进行下载;
6、本站部分资源文件是经压缩后的,请下载后安装解压软件,推荐使用WinRAR和7-Zip解压软件。
7、如果本站提供的资源侵犯到了您的权益,请邮件联系: 442469558@qq.com 进行处理!

猪小侠源码-最新源码下载平台 Java教程 SpringBoot利用AOP实现一个日志管理详解 https://www.20zxx.cn/704792/xuexijiaocheng/javajc.html

猪小侠源码,优质资源分享网

常见问题
  • 本站所有资源版权均属于原作者所有,均只能用于参考学习,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担
查看详情
  • 最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,建议提前注册好百度网盘账号,使用百度网盘客户端下载
查看详情

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务