基于AOP实现登录日志和操作日志(新手入门版)

这篇具有很好参考价值的文章主要介绍了基于AOP实现登录日志和操作日志(新手入门版)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录结构

基于AOP实现登录日志和操作日志(新手入门版),技术,JavaAOP,java,spring boot

代码


package com.demo.mymaintest.constants;

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

/**
 * 系统日志注解
 *
 * @author Mark sunlightcs@gmail.com
 */
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Target({ElementType.METHOD,ElementType.PARAMETER })
public @interface SysLog {

	String value() default "";

}

package com.demo.mymaintest.aop;


import com.alibaba.fastjson.JSONObject;
import com.demo.mymaintest.constants.SysLog;
import com.demo.mymaintest.entity.SysLogEntity;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
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.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;


import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 系统日志,切面处理类
 *
 * @author yhj
 */
@Aspect
@Component
public class SysLogAspect {

  // 定义切点 切点表达式指向SysLog注解,我们再业务方法上可以加上SysLog注解,然后所标注
  // 的方法都能进行日志记录
  @Pointcut("@annotation(com.demo.mymaintest.constants.SysLog)")
  public void logPointCut() {}

  @Around(value = "logPointCut()")
  private Object Around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
    HttpServletRequest request  = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
    String requestURI = request.getRequestURI();
    String requestMethod = request.getMethod();
    String remoteAddr = request.getRemoteAddr();
    SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    Long nowDate = System.currentTimeMillis(); // 步入时间戳
    String startTime = dateformat.format(nowDate);

    MethodSignature method1 = (MethodSignature) proceedingJoinPoint.getSignature();
    Class<?> currentClass = proceedingJoinPoint.getTarget().getClass();
    Object proceed = proceedingJoinPoint.proceed();
    List<Object> allArgs = Arrays.asList(proceedingJoinPoint.getArgs());
    List<Object> args =
        allArgs.stream()
            .map(
                arg -> {
                  if (!(arg instanceof HttpServletRequest)
                      && !(arg instanceof HttpServletResponse)) {
                    return arg;
                  } else {
                    return null;
                  }
                })
            .filter(arg -> arg != null)
            .collect(Collectors.toList());

    SysLogEntity sysLogEntity = new SysLogEntity();
    sysLogEntity.setUsername("登录人从request中获取");
    MethodSignature signature = (MethodSignature) proceedingJoinPoint.getSignature();
    		Method method = signature.getMethod();
    SysLog syslog = method.getAnnotation(SysLog.class);
    if(syslog != null){
            //注解上的描述
            sysLogEntity.setOperation(syslog.value());
        }
    sysLogEntity.setRequestPath(requestURI);
    sysLogEntity.setRequestMethod(requestMethod);
    sysLogEntity.setCurrentTimeMills(startTime);
    sysLogEntity.setArgsType(getMethodArgumentTypeName(method1));
    sysLogEntity.setAllArgs(args);
    sysLogEntity.setResponseData(proceed != null ? proceed.toString() : "null");
    sysLogEntity.setExecuteTimeMills((System.currentTimeMillis() - nowDate) + "ms");
    sysLogEntity.setClassMethodLocation(currentClass.getName() + "." + method.getName());
    sysLogEntity.setRemoteAddr(remoteAddr);
    sysLogEntity.setNowTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
    sysLogEntity.setResponseType(method.getReturnType().getName());

    // TODO 将sysLogEntity存入ES

    System.out.println(JSONObject.toJSONString(sysLogEntity));
    return proceed;
  }

  @AfterThrowing(value = "logPointCut()")
  private void AfterThrowing() {
    System.out.println("异常通知");
  }

  private Map<String, String> getMethodArgumentTypeName(MethodSignature method) {
    Map<String, String> map = new HashMap<>();
    String[] argTypeNames = method.getParameterNames();
    Class[] parameterTypes = method.getParameterTypes();
    for (int i = 0; i < parameterTypes.length; i++) {
      map.put(parameterTypes[i].getName(), argTypeNames[i]);
    }
    return map;
  }
}
package com.demo.mymaintest.controller;


import com.demo.mymaintest.constants.SysLog;
import com.demo.mymaintest.entity.BookEntity;
import com.demo.mymaintest.entity.SysUser;
import com.demo.mymaintest.utils.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;

import org.springframework.web.bind.annotation.*;

/**
 * @ClassName TestApiController
 * @Author yhj
 * @Date 2023/7/15 13:22
 * @Description
 * @Version 1.0
 */

@RestController
@RequestMapping("/api")
@Slf4j
public class TestApiController {

    @PostMapping("/add")
    @SysLog(value = "添加数据测试")
    public R test(@RequestBody BookEntity bookEntity) {
        bookEntity.setBookImg("testImg");
        bookEntity.setBookIntro("书籍简介");
        return R.ok(200,"添加成功",bookEntity);
    }
    @PostMapping("/login")
    @SysLog(value = "用户登录")
    public ResponseEntity login(@RequestBody SysUser sysUser){
            String ok = "恭喜你登录成功";
            if(sysUser.getUserName().equals("test")){
                return ResponseEntity.ok(ok);
            }
            return ResponseEntity.ok().body("登录失败");
    }
    @DeleteMapping("/delete")
    @SysLog("删除")
    public ResponseEntity<String> deleteById(@PathVariable("id") Integer id){
        return ResponseEntity.ok("删除成功");
    }
}

package com.demo.mymaintest.entity;

import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

import java.io.Serializable;

/**
 *
 *
 * @author yhj
 * @date 2023-06-12 09:47:10
 */
@Data
public class BookEntity implements Serializable {
	private static final long serialVersionUID = 1L;
	/**
	 *
	 */
	@TableId
	private Integer bookId;
	/**
	 * 书籍编号
	 */
	private String bookIsbn;
	/**
	 * 书籍名称
	 */
	private String bookName;
	/**
	 * 书籍价格
	 */
	private Float bookPrice;

	/**
	 * 书籍封面
	 */
	private String bookImg;
	/**
	 * 简介
	 */
	private String bookIntro;
	/**
	 * 已购数量
	 */
	private int bookPurchasedNumber;
}

package com.demo.mymaintest.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;

import java.io.Serializable;
import java.util.Date;

/**
 * <p>
 * 用户表
 * </p>
 *
 * @author jerry
 * @since 2021-06-16
 */
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)

public class SysUser implements Serializable {

private static final long serialVersionUID=1L;

    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    /**
     * 用户编号
     */
    //@ApiModelProperty("用户编号")
    private String userCode;

    /**
     * 用户名
     */
    //@ApiModelProperty("用户名")
    private String userName;

    /**
     * 登录密码
     */
    //@ApiModelProperty("登录密码")
    private String password;

    /**
     * 真实姓名
     */
    //@ApiModelProperty("真实姓名")
    private String realName;

    /**
     * 手机号码
     */
    //@ApiModelProperty("手机号码")
    private String mobile;

    /**
     * 邮箱地址
     */
    //@ApiModelProperty("邮箱地址")
    private String email;

    /**
     * 组织机构id
     */
    //@ApiModelProperty("组织机构id")
    private Long orgId;

    /**
     * 组织机构名称
     */
    //@ApiModelProperty("组织机构名称")
    private String orgName;

    /**
     * 用户类型
     */
    //@ApiModelProperty("用户类型")
    private Integer userType;

    /**
     * 描述
     */
    //@ApiModelProperty("描述")
    private String userDesc;

    /**
     * 联系地址
     */
    //@ApiModelProperty("联系地址")
    private String address;

    /**
     * 传真
     */
    //@ApiModelProperty("传真")
    private String fax;

    /**
     * 邮编
     */
    //@ApiModelProperty("邮编")
    private String postalcode;

    /**
     * 状态(0:禁用 1:正常)
     */
    //@ApiModelProperty("状态(0:禁用 1:正常)")
    private Integer status;

    /**
     * 数据权限类型(role user group)
     */
    //@ApiModelProperty("数据权限类型(role user group)")
    private String permissionType;

    /**
     * 创建时间
     */
    //@ApiModelProperty("创建时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date createTime;

    /**
     * 创建人
     */
    //@ApiModelProperty("创建人")
    private String createBy;

    /**
     * 更新时间
     */
    //@ApiModelProperty("更新时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date updateTime;

    /**
     * 更新人
     */
    //@ApiModelProperty("更新人")
    private String updateBy;

    /**
     * 是否删除(0-否 1-是)
     */
    //@ApiModelProperty("是否删除(0-否 1-是)")
    private Integer isDeleted;

    /**
     * 公司地址
     */
    //@ApiModelProperty("公司地址")
    private String orgAddress;

    /**
     * 部门id
     */
    //@ApiModelProperty("部门id")
    private String jobId;

    /**
     * 部门名称
     */
    //@ApiModelProperty("部门名称")
    private String jobName;


    /**
     * 过期期限
     */
    //@ApiModelProperty("过期期限")
    @JsonFormat(pattern = "yyyyMM", timezone = "GMT+8")
    private Date expire;

    private String orgCode;

}

PostMan测试代码

基于AOP实现登录日志和操作日志(新手入门版),技术,JavaAOP,java,spring boot

控制台查看输出

基于AOP实现登录日志和操作日志(新手入门版),技术,JavaAOP,java,spring boot文章来源地址https://www.toymoban.com/news/detail-605160.html

解析成JSON

{
    "allArgs":[                           // 所有入参
        {
            "bookId":123,
            "bookImg":"testImg",
            "bookIntro":"书籍简介",
            "bookIsbn":"123213414",
            "bookName":"test",
            "bookPrice":12.77,
            "bookPurchasedNumber":0
        }
    ],
    "argsType":{                        // 入参实体类
        "com.demo.mymaintest.entity.BookEntity":"bookEntity"
    },
    "classMethodLocation":"com.demo.mymaintest.controller.TestApiController.test",     // 方法
    "currentTimeMills":"2023-07-21 16:30:49",     // 时间
    "executeTimeMills":"9ms",   // 运行时间
    "nowTime":"2023-07-21 16:30:49",  // 时间
    "operation":"添加数据测试",      //  controller上面的注释
    "remoteAddr":"0:0:0:0:0:0:0:1",  // 这个其实是127.0.0.1 没有进行封装
    "requestMethod":"POST",       
    "requestPath":"/api/add",     // 路径  
    "responseData":"{msg=添加成功, code=200, data=BookEntity(bookId=123, bookIsbn=123213414, bookName=test, bookPrice=12.77, bookImg=testImg, bookIntro=书籍简介, bookPurchasedNumber=0)}",
    "responseType":"com.demo.mymaintest.utils.R",    // 所有返参
    "username":"登录人从request中获取"     // 根据项目详情从token或者session中获取登录人
}

如果你觉得对你有帮助的话,请点赞收藏

到了这里,关于基于AOP实现登录日志和操作日志(新手入门版)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Visual Studio 新手入门指导】包括项目创建、常用快捷键、美化、项目启动、添加文件等多种基础操作,图文详细,准确无误

    本文来自于作者在Visual Studio的使用过程中自己积累经验的总结,主要介绍一些比较实用的技巧,适合新手入门使用。 内容追求细致、有用、基础。 VS的每次运行的是一个一个的项目 (如果有多个项目,则每次执行选定启动项目,后文有所介绍),但是不同项目在一起构成一

    2024年02月08日
    浏览(57)
  • 一个基于SpringBoot开发的RBAC系统,非常适合新手入门JavaWeb代码审计实战的系统,长文警告,要好好学习。

    嗨,大家好,我是闪石星曜CyberSecurity创始人Power7089。 欢迎大家搜索我的微信公众号:闪石星曜CyberSecurity 本文是【炼石计划@Java代码审计】内部圈子原创课程,现分享给大家学习。 如需转载,请详细注明来源。 欢迎大家搜索并添加我的好友【Power_7089】,备注CSDN,邀请你进入

    2024年02月11日
    浏览(50)
  • ue4/5蓝图与c++混用基础入门的基础操作(适合有蓝图基础和c++基础的新手,创建自己的蓝图)

            首先是最开始的创建项目,用c++模式进行创建。         ue4:         ue5:  创建之后,两个都会自动为你打开vs,不过ue4.26要的是vs2019,ue5要的是vs2022,有时候打不开是缺少一些东西,这些东西在csdn里面可以查到,作者就不细讲了。 在ue5(4是一样的)中,我们可

    2023年04月12日
    浏览(48)
  • Spring Boot入门(23):基于AOP实现自定义注解拦截接口日志并保存入库 | 超级详细,建议收藏

            在上两期中,我们着重介绍了如何集成使用 Logback 与 log4j2 日志框架的使用,今天我们讲解的主题依旧跟日志有关,不过不是使用何种开源框架,而是自己动手造。         Spring的核心之一AOP;AOP翻译过来叫面向切面编程, 核心就是这个切面. 切面表示从业务逻辑中

    2024年02月11日
    浏览(48)
  • GitHub新手用法详解【适合新手入门-建议收藏!!!】

    目录 什么是Github,为什么使用它? 一、GitHub账号的注册与登录 二、 gitbash安装详解 1.git bash的下载与安装 2.git常用命令  3. Git 和 GitHub 的绑定 1. 获取SSH keys  2.绑定ssh密钥 三、通过Git将代码提交到GitHub 1.克隆仓库   2.测试提交代码         GitHub是一个面向开源及私有软件项

    2023年04月24日
    浏览(58)
  • HLS新手入门教程

    HLS是一种高级综合技术,它允许开发人员使用高级语言(如C、C++和SystemC)来描述数字电路的行为和功能,然后将其转换为硬件电路实现。这种转换过程是自动完成的,因此开发人员无需手动编写硬件描述语言(HDL)。 HLS的主要目的是简化FPGA设计流程,提高设计效率和设计质

    2024年02月02日
    浏览(54)
  • uniapp基础(新手入门)

    前言: 这篇文章主要写的是uniapp的基础知识,可以让大家快速上手uniapp,同时避掉一些可能踩到的坑。 uniapp是由 dcloud 公司开发的多端融合框架。uniapp的出现让我们的开发更为方便,一次开发,多端运行。更重要的是学习成本不会很大,因为uniapp主要是Vue语法加上小程序的

    2024年02月12日
    浏览(43)
  • Midjourney新手入门指南

    我们来看一下百度百科的回复 是不是有点蒙,没关系,一句话概括:用描述来生成图像的AI工具。 你可能又有一门了,discord是什么?为什么要下载它?我们来看看百度百科 原因:Midjouney 没有自己的客户端,它是搭载在Discord上。 Discord 简单来说,就是一个聊天应用。

    2024年02月10日
    浏览(69)
  • PyCharm新手入门指南

    安装好Pycharm后,就可以开始编写第一个函数:Hello World啦~我们就先来学习一些基本的操作,主要包含新建Python文件,运行代码,查看结果等等。 文章主要包含五个部分: 一、界面介绍 主要分为菜单栏、项目目录、编辑区域、终端区和运行/调试代码区域。 1、菜单栏:一些新

    2024年02月13日
    浏览(52)
  • StarkNet新手入门教程:教你用bitget 钱包入门

    理想的Starknet (web3.bitget.com/zh/assets/starknet-wallet) 钱包取决于个人喜好,同时考虑安全性、用户友好性、帐户恢复选项和多通证支持等因素。尽管如此,无论您使用 Starknet (STRK) 的目的是持有还是交易,Bitget Wallet 都是您管理 STRK 以及其他以太坊和 Optimism 加密资产的理想钱包选择

    2024年03月12日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包