iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >Java自定义注解@Log和AOP实现用户操作日志
  • 593
分享到

Java自定义注解@Log和AOP实现用户操作日志

javaspringbootmysqlrestful 2023-10-03 08:10:29 593人浏览 泡泡鱼
摘要

        1、实现前准备,Mysql数据库中创建表 CREATE TABLE `sys_log` ( `oper_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '日志主键', `ti

        1、实现前准备,Mysql数据库中创建表

CREATE TABLE `sys_log` (  `oper_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '日志主键',  `title` varchar(50) DEFAULT '' COMMENT '模块标题',  `business_type` int(11) DEFAULT '0' COMMENT '业务类型(0其它 1新增 2修改 3删除)',  `method` varchar(100) DEFAULT '' COMMENT '方法名称',  `request_method` varchar(10) DEFAULT '' COMMENT '请求方式',  `operator_type` int(11) DEFAULT '0' COMMENT '操作类别( 0、用户端   1、平台管理端)',  `oper_name` varchar(50) DEFAULT '' COMMENT '操作人员',  `oper_url` varchar(255) DEFAULT '' COMMENT '请求URL',  `oper_ip` varchar(128) DEFAULT '' COMMENT '主机地址',  `oper_location` varchar(255) DEFAULT '' COMMENT '操作地点',  `oper_param` varchar(2000) DEFAULT '' COMMENT '请求参数',  `JSON_result` varchar(2000) DEFAULT '' COMMENT '返回参数',  `status` int(11) DEFAULT '0' COMMENT '操作状态(1正常 0异常)',  `error_msg` varchar(2000) DEFAULT '' COMMENT '错误消息',  `oper_time` datetime DEFAULT NULL COMMENT '操作时间',  PRIMARY KEY (`oper_id`) USING BTREE) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='操作日志记录';

        2、依赖(aop依赖,至于其他依赖(Druid,mybatisPlus)自行处理)

                            org.springframework.boot            spring-boot-starter-aop        

        3、自定义注解(具体如何自定义注解,请自行学习,这里不做详细说明)

import com.xiarg.genius.annotation.entry.BusinessTypeEnum;import java.lang.annotation.*;@Target({ElementType.METHOD,ElementType.PARAMETER})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface Log {        public String title() default "";        public BusinessTypeEnum businessType() default BusinessTypeEnum.OTHER;}

        4、切面

import com.alibaba.fastjson2.JSON;import com.xiarg.genius.annotation.annotation.Log;import com.xiarg.genius.annotation.entry.SysLog;import com.xiarg.genius.annotation.service.ISysLogService;import lombok.Data;import org.aspectj.lang.JoinPoint;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.bind.annotation.RequestMethod;import org.springframework.web.context.request.RequestContextHolder;import org.springframework.web.context.request.ServletRequestAttributes;import org.springframework.web.multipart.MultipartFile;import org.springframework.web.servlet.HandlerMapping;import javax.servlet.Http.httpservletRequest;import javax.servlet.http.HttpServletResponse;import java.time.LocalDateTime;import java.util.Collection;import java.util.Map;@Data@Aspect@Componentpublic class LoGConfig {    private static final Logger log = LoggerFactory.getLogger(LogConfig.class);        private final ISysLogService sysLogService;        @Pointcut("@annotation(com.xiarg.genius.annotation.annotation.Log)")    public void logPointCut() {}        @AfterReturning(pointcut = "@annotation(controllerLog)", returning = "jsonResult")    public void doAfterReturning(JoinPoint joinPoint, Log controllerLog, Object jsonResult){        handleLog(joinPoint, controllerLog, null, jsonResult);    }        @AfterThrowing(value = "@annotation(controllerLog)", throwing = "e")    public void doAfterThrowing(JoinPoint joinPoint, Log controllerLog, Exception e){        handleLog(joinPoint, controllerLog, e, null);    }        protected void handleLog(final JoinPoint joinPoint, Log controllerLog, final Exception e, Object jsonResult){        try {            MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();            // 获取当前的用户            String userName = "genius";            // *========数据库日志=========*//            SysLog sysLog = new SysLog();            sysLog.setStatus(1);            // 请求的地址 ip和localtion是前端获取到传过来的            ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();            assert requestAttributes != null;            HttpServletRequest request = requestAttributes.getRequest();            Map parameterMap = request.getParameterMap();            String ip = getIpAddr(request);            sysLog.setOperIp(ip);            sysLog.setOperLocation(request.getHeader("location"));            sysLog.setOperParam(JSON.toJSONString(parameterMap));            sysLog.setOperUrl(request.getRequestURI());            sysLog.setOperName(userName);            if (e != null) {                sysLog.setStatus(0);                int length = e.getMessage().length();                sysLog.setErrorMsg(e.getMessage().substring(0,length>2000?2000:length));            }            // 设置方法名称            String className = joinPoint.getTarget().getClass().getName();            String methodName = joinPoint.getSignature().getName();            sysLog.setMethod(className + "." + methodName + "()");            // 设置请求方式            sysLog.setRequestMethod(request.getMethod());            // 处理设置注解上的参数            getControllerMethodDescription(joinPoint, controllerLog, sysLog, jsonResult, request);            // 保存数据库            sysLog.setOperTime(LocalDateTime.now());            // 返回数据            sysLog.setJsonResult(jsonResult==null?"":jsonResult.toString());            // 将处理好的日至对象存储进数据库            sysLogService.save(sysLog);        } catch (Exception exp) {            // 记录本地异常日志            log.error("==前置通知异常==");            log.error("异常信息:{}", exp.getMessage());            exp.printStackTrace();        }    }        public static String getIpAddr(HttpServletRequest request) {        if (request == null) {            return "unknown";        }        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("X-Forwarded-For");        }        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("X-Real-IP");        }        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {            ip = request.getRemoteAddr();        }        return ip;    }        public void getControllerMethodDescription(JoinPoint joinPoint, Log log, SysLog sysLog, Object jsonResult, HttpServletRequest request) throws Exception {        // 设置action动作        sysLog.setBusinessType(log.businessType().ordinal());        sysLog.setTitle(log.title());    }    private void setRequestValue(JoinPoint joinPoint, SysLog sysLog, HttpServletRequest request) throws Exception {        String requestMethod = sysLog.getRequestMethod();        if (RequestMethod.PUT.name().equals(requestMethod) || RequestMethod.POST.name().equals(requestMethod)) {            String params = argsArrayToString(joinPoint.getArgs());            sysLog.setOperParam(params.substring(0,2000));        } else {            Map paramsMap = (Map) request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);            sysLog.setOperParam(paramsMap.toString().substring(0,2000));        }    }        private String argsArrayToString(Object[] paramsArray) {        StringBuilder params = new StringBuilder();        if (paramsArray != null && paramsArray.length > 0) {            for (Object o : paramsArray) {                if (o != null && !isFilterObject(o)) {                    try {                        Object jsonObj = JSON.toJSON(o);                        params.append(jsonObj.toString()).append(" ");                    } catch (Exception e) {                        log.error(e.getMessage());                    }                }            }        }        return params.toString().trim();    }    @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;    }}

        5、枚举和实体类

public enum BusinessTypeEnum {        OTHER,        INSERT,        UPDATE,        DELETE,        GRANT,}
import com.baomidou.mybatisplus.annotation.IdType;import com.baomidou.mybatisplus.annotation.TableId;import lombok.Data;import java.time.LocalDateTime;@Datapublic class SysLog {    @TableId(value = "oper_id", type = IdType.AUTO)    private Long operId;    private String title;    private Integer businessType;    private String method;    private String requestMethod;    private String operName;    private String operUrl;    private String operIp;    private String operLocation;    private String operParam;    private String jsonResult;    private Integer status;    private String errorMsg;    private LocalDateTime operTime;}

        6、具体的控制层应用

import com.xiarg.genius.annotation.annotation.Log;import com.xiarg.genius.annotation.entry.BusinessTypeEnum;import org.springframework.web.bind.annotation.*;@RestController@RequestMapping("test")public class TestController {    @Log(title = "查询列表",businessType = BusinessTypeEnum.OTHER)    @GetMapping()    public String list(@RequestParam("id") String id) {        return "返回数据列表";    }    @Log(title = "添加数据",businessType = BusinessTypeEnum.INSERT)    @PostMapping    public String save() {        try {            System.out.println(1/0);        } catch (Exception e) {            throw e;        }        return "数据添加成功";    }    @Log(title = "修改数据",businessType = BusinessTypeEnum.UPDATE)    @PutMapping    public String update() {        return "修改数据成功";    }    @Log(title = "删除数据",businessType = BusinessTypeEnum.DELETE)    @DeleteMapping    public String delete() {        return "删除数据成功";    }}

        7、综上即实现功能,但是注意:ip和localtion是前端获取到传过来的,要不然无法获取到。

来源地址:https://blog.csdn.net/m0_65014849/article/details/129818219

您可能感兴趣的文档:

--结束END--

本文标题: Java自定义注解@Log和AOP实现用户操作日志

本文链接: https://www.lsjlt.com/news/422937.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java自定义注解@Log和AOP实现用户操作日志
            1、实现前准备,MySQL数据库中创建表 CREATE TABLE `sys_log` ( `oper_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '日志主键', `ti...
    99+
    2023-10-03
    java spring boot mysql restful
  • Spring AOP实现复杂的日志记录操作(自定义注解)
    目录Spring AOP复杂的日志记录(自定义注解)第一步第二步第三步第四步多个注解可以合并成一个,包括自定义注解比如说SpringMVC的注解Spring AOP复杂的日志记录(自...
    99+
    2022-11-12
  • springboot使用自定义注解实现aop切面日志
    平时我们在开发过程中,代码出现bug时为了更好的在服务器日志中寻找问题根源,会在接口的首尾打印日志,看下参数和返回值是否有问题。但是手动的logger.info() 去编写时工作量较...
    99+
    2022-11-13
  • SpringBoot自定义注解之实现AOP切面日志详解
    通过自定义注解的方式(如:@SysLog(obj = "操作对象", text = "操作内容"),在 SpringBoot 中来实现 AOP...
    99+
    2022-11-13
  • 使用java注解和aspectj AOP怎么实现打印日志
    本篇文章给大家分享的是有关使用java注解和aspectj AOP怎么实现打印日志,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。首先需要自定义注解:systemName:表示该...
    99+
    2023-06-06
  • SpringBoot中利用AOP和拦截器实现自定义注解
    目录前言Spring实现自定义注解1.引入相关依赖2.相关类Java实现自定义注解通过Cglib实现通过JDk动态代理实现Cglib和JDK动态代理的区别写在最后前言 最近遇到了这样...
    99+
    2022-11-13
  • Spring AOP使用@Aspect注解 面向切面实现日志横切的操作
    引言: AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续...
    99+
    2022-11-12
  • 使用自定义Json注解实现输出日志字段脱敏
    自定义Json注解实现输出日志字段脱敏 背景 在日志输出的时候,有时会输出一些用户的敏感信息,如手机号,身份证号,银行卡号等,现需要对这些信息在日志输出的时候进行脱敏处理 思路 使用...
    99+
    2022-11-12
  • SpringBoot中怎么利用AOP和拦截器实现自定义注解
    本篇内容主要讲解“SpringBoot中怎么利用AOP和拦截器实现自定义注解”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“SpringBoot中怎么利用AOP和拦截器实现自定义注解”吧!Spri...
    99+
    2023-07-02
  • 如何使用自定义Json注解实现输出日志字段脱敏
    这篇文章给大家分享的是有关如何使用自定义Json注解实现输出日志字段脱敏的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。自定义Json注解实现输出日志字段脱敏背景在日志输出的时候,有时会输出一些用户的敏感信息,如手...
    99+
    2023-06-22
  • Java操作MyBatis-Plus通过自定义拦截器对mysql字段以注解形式实现自动加解密
    一.需求背景 跟大学室友闲谈时,了解到他公司正在做项目内对数据库敏感字段实现自动加解密的需求,使用的技术是Springboot,Mybatis-Plus,MySql等技术栈,加密算法是用的AES,密钥是放在华为云,这里实现一个阉割版的dem...
    99+
    2023-09-06
    mybatis mysql java
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作