IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> springboot通用日志实现+自定义注解+AOP(代码全!!!) -> 正文阅读

[Java知识库]springboot通用日志实现+自定义注解+AOP(代码全!!!)

介绍

我们在进行项目开发时经常会使用得logback/log4j+slf4j进行日志控制,这有助于我们记录用户操作和错误排查,更重要得是这是甩锅利器(0.0)。
然而有些时候,客户要求记录敏感操作信息入库,这就需要我们进行更详细得日志记录操作。
废话不多说直接上代码
以下代码只是个Demo,仅供参考和学习。

AOP + 自定义注解

面向切面编程,用来强化功能。这个就不多介绍了,请自行百度。你可以的!
注解这玩意,在实际开发中肯定没少用,大家也知道注解得好处。减少配置,拿来就用,方便!

自定义注解 SysLog

/**
 * 日志注解
 * @author finn
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SysLog {
    String value() default "";
}

AOP切面 SysLogAspect

/**
 * 日志切面类
 */
@Aspect
@Component
public class SysLogAspect {
    @Resource
    private SysLogService sysLogService;

    @Pointcut(value = "@annotation(com.finn.springbootmp.annotation.SysLog)")
    public void logPointCut() {
    }

    @Around("logPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {

        long beginTime = System.currentTimeMillis();

        //执行方法
        Object result = point.proceed();

        long time = System.currentTimeMillis() - beginTime;
        //保存日志
        saveSysLog(point, time, result);
        return result;
    }

    private void saveSysLog(ProceedingJoinPoint point, long time, Object result) {
        //获取方法信息
        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();
        //日志实体类
        SysLogEntity sysLogEntity = new SysLogEntity();
        //获取注解信息
        SysLog sysLog = method.getAnnotation(SysLog.class);
        if (sysLog != null) {
            sysLogEntity.setOperation(sysLog.value());
        }
        //添加请求方法
        String className = point.getTarget().getClass().getName();
        String methodName = signature.getName();
        sysLogEntity.setMethod(className + "." + methodName + "()");

        //添加请求参数
        Object[] args = point.getArgs();
        String params = JSONObject.toJSONString(args);
        sysLogEntity.setParams(params);

        //添加真实IP
        HttpServletRequest request = getHttpServletRequest();
        sysLogEntity.setIpAddress(IpUtils.getIpAddress(request));

        /**
         * 另外实际项目中会获取到当前操作人得相关信息,
         * 可以按需添加
         */

        //其他信息
        sysLogEntity.setOperateTime(time);
        sysLogEntity.setCreateDate(new Date());
        sysLogService.save(sysLogEntity);
    }


    /**
     * 获取当前请求
     * @return
     */
    public HttpServletRequest getHttpServletRequest() {
        return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
    }
    
}

日志实体类 SysLogEntity

/**
 * 日志实体类
 */
@Data
@TableName("sys_log")
public class SysLogEntity implements Serializable
{
    private static final long serialVersionUID = 1L;

    @TableId("id")
    private Long id;

    //用户名
    private String userName;

    //用户操作
    private String operation;

    //请求方法
    private String method;

    //请求参数
    private String params;

    //执行时常
    private Long operateTime;

    //ip地址
    private String ipAddress;

    //创建世间
    private Date createDate;

    //日志类别
    private String logType;

    //状态
    private int status;

}

ip工具类 IpUtils

    /**
     * 获取真实ip
     * @param request
     * @return
     */
    public static String getIpAddress(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }
}

sys_log 表sql

DROP TABLE IF EXISTS `sys_log`;
CREATE TABLE `sys_log`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `user_name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '用户名',
  `operation` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '用户操作',
  `method` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '请求方法',
  `params` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '请求参数',
  `operate_time` bigint(20) NULL DEFAULT NULL COMMENT '执行时间',
  `ip_address` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'ip地址',
  `create_date` datetime(0) NOT NULL COMMENT '创建时间',
  `status` tinyint(2) NULL DEFAULT NULL COMMENT '状态',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1427633902284976130 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

测试

测试代码

@RestController
@RequestMapping("/sys-user")
public class SysUserController {
    @Autowired
    private ISysUserService iSysUserService;

    @SysLog("通用日志处理测试")
    @RequestMapping("/test")
    public boolean test(@RequestParam("username") String username,@RequestParam("password") String password){
        SysUser sysUser = new SysUser();
        sysUser.setUsername(username);
        sysUser.setPassword(password);
        boolean save = iSysUserService.save(sysUser);
        return save;
    }

}

请求测试

http://127.0.0.1:8080/sys-user/test?username=finn&password=finn321

结果:

在这里插入图片描述

注意

使用localhost作为地址测试时,ip存入有问题,使用127.0.0.1就好

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-08-19 11:55:18  更:2021-08-19 11:55:29 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/21 1:34:34-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码