gpt4 book ai didi

通过AOP拦截SpringBoot日志并将其存入数据库

转载 作者:我是一只小鸟 更新时间:2023-08-31 07:38:27 31 4
gpt4 key购买 nike

本文分享自华为云社区《 Spring Boot入门(23):【实战】通过AOP拦截Spring Boot日志并将其存入数据库 》,作者:bug菌.

前言

在软件开发中,常常需要记录系统运行时的日志。日志记录有助于排查系统问题、优化系统性能、监控操作行为等。本文将介绍如何使用Spring Boot和AOP技术实现拦截系统日志并保存到数据库中的功能.

摘要

本文将通过以下步骤实现拦截系统日志并保存到数据库中的功能:

  1. 配置数据库连接
  2. 定义日志实体类
  3. 定义日志拦截器
  4. 使用AOP拦截日志并保存到数据库中

AOP介绍

AOP,全称是Aspect Oriented Programming,即面向切面编程。AOP的目的是将那些与业务无关,但是业务模块都需要的功能,如日志统计、安全控制、事务处理等,封装成可重用的组件,从而将它们从业务逻辑代码中划分出来,编写成独立的切面。这样做,既可以保持业务逻辑的纯净和高内聚性,又可以使得系统的多个模块都可以共享这些公共的功能.

Spring框架提供了对AOP的支持,Spring Boot自然也不例外。使用Spring Boot的AOP功能,我们可以在运行时动态地将代码横向切入到各个关注点(方法或者类)中。这种横向切面的方式,比传统的纵向切面(继承)更加灵活.

AOP的实现

添加依赖

在pom.xml中添加以下依赖:

                          <dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-aop</artifactId>

</dependency>

<dependency>

<groupId>org.mybatis.spring.boot</groupId>

<artifactId>mybatis-spring-boot-starter</artifactId>

</dependency>
                        

这样我们就可以使用Spring Boot的AOP功能和MyBatis框架.

配置数据库连接

首先需要在Spring Boot项目的application.properties文件中配置数据库连接信息:

                          spring.datasource.url=jdbc:mysql:
                          
                            //
                          
                          
                            localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false
                          
                          
                            
spring.datasource.username
                          
                          =
                          
                            root

spring.datasource.password
                          
                          =
                          
                            123456
                          
                          
                            

spring.datasource.driver
                          
                          -
                          
                            class
                          
                          -name=com.mysql.jdbc.Driver
                        

或者你也可以使用YAML的配置格式:

cke_123.png

定义日志实体类

定义一个Log实体类用于保存日志信息,并使用@Entity和@Table注解指定对应的数据库表和字段:

                          
                            @Entity

@Table(name 
                          
                          = 
                          
                            "
                          
                          
                            sys_log
                          
                          
                            "
                          
                          
                            )


                          
                          
                            public
                          
                          
                            class
                          
                          
                             Log {

@Id

@GeneratedValue(strategy 
                          
                          =
                          
                             GenerationType.IDENTITY)


                          
                          
                            private
                          
                          
                             Long id;


                          
                          
                            private
                          
                          
                             String username;


                          
                          
                            private
                          
                          
                             String operation;


                          
                          
                            private
                          
                          
                             String method;


                          
                          
                            private
                          
                           String 
                          
                            params
                          
                          
                            ;


                          
                          
                            private
                          
                          
                             String ip;


                          
                          
                            private
                          
                          
                             Date createTime;


                          
                          
                            //
                          
                          
                             省略getter和setter方法
                          
                          
                            
}
                          
                        

定义日志拦截器

定义一个日志拦截器LogInterceptor,通过实现HandlerInterceptor接口来拦截请求并记录日志:

                          
                            @Component


                          
                          
                            public
                          
                          
                            class
                          
                          
                             LogInterceptor implements HandlerInterceptor {

@Autowired


                          
                          
                            private
                          
                          
                             LogRepository logRepository;

@Override


                          
                          
                            public
                          
                          
                             boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {


                          
                          
                            //
                          
                          
                             获取请求的IP地址
                          
                          
                            
String ip 
                          
                          =
                          
                             getIpAddress(request);


                          
                          
                            //
                          
                          
                             获取当前用户
                          
                          
                            
String username 
                          
                          =
                          
                             getCurrentUsername();


                          
                          
                            //
                          
                          
                             获取请求的方法名
                          
                          
                            
String method 
                          
                          =
                          
                             request.getMethod();


                          
                          
                            //
                          
                          
                             获取请求的URL
                          
                          
                            
String url 
                          
                          =
                          
                             request.getRequestURI();


                          
                          
                            //
                          
                          
                             获取请求的参数
                          
                          
                            
String 
                          
                          
                            params
                          
                           =
                          
                             getParams(request);


                          
                          
                            //
                          
                          
                             创建日志实体
                          
                          
                            
Log log 
                          
                          = 
                          
                            new
                          
                          
                             Log();

log.setIp(ip);

log.setMethod(method);

log.setOperation(
                          
                          
                            "
                          
                          
                            访问
                          
                          
                            "
                          
                          
                            );

log.setParams(
                          
                          
                            params
                          
                          
                            );

log.setUsername(username);

log.setCreateTime(
                          
                          
                            new
                          
                          
                             Date());


                          
                          
                            //
                          
                          
                             保存日志到数据库中
                          
                          
                            
logRepository.save(log);




                          
                          
                            return
                          
                          
                            true
                          
                          
                            ;

}


                          
                          
                            //
                          
                          
                             省略实现HandlerInterceptor接口的其他方法
                          
                          
                            /*
                          
                          
                            *

* 获取请求的IP地址


                          
                          
                            */
                          
                          
                            private
                          
                          
                             String getIpAddress(HttpServletRequest request) {

String ip 
                          
                          = request.getHeader(
                          
                            "
                          
                          
                            X-Forwarded-For
                          
                          
                            "
                          
                          
                            );


                          
                          
                            if
                          
                           (StringUtils.isBlank(ip) || 
                          
                            "
                          
                          
                            unknown
                          
                          
                            "
                          
                          
                            .equalsIgnoreCase(ip)) {

ip 
                          
                          = request.getHeader(
                          
                            "
                          
                          
                            Proxy-Client-IP
                          
                          
                            "
                          
                          
                            );

}


                          
                          
                            if
                          
                           (StringUtils.isBlank(ip) || 
                          
                            "
                          
                          
                            unknown
                          
                          
                            "
                          
                          
                            .equalsIgnoreCase(ip)) {

ip 
                          
                          = request.getHeader(
                          
                            "
                          
                          
                            WL-Proxy-Client-IP
                          
                          
                            "
                          
                          
                            );

}


                          
                          
                            if
                          
                           (StringUtils.isBlank(ip) || 
                          
                            "
                          
                          
                            unknown
                          
                          
                            "
                          
                          
                            .equalsIgnoreCase(ip)) {

ip 
                          
                          = request.getHeader(
                          
                            "
                          
                          
                            HTTP_CLIENT_IP
                          
                          
                            "
                          
                          
                            );

}


                          
                          
                            if
                          
                           (StringUtils.isBlank(ip) || 
                          
                            "
                          
                          
                            unknown
                          
                          
                            "
                          
                          
                            .equalsIgnoreCase(ip)) {

ip 
                          
                          = request.getHeader(
                          
                            "
                          
                          
                            HTTP_X_FORWARDED_FOR
                          
                          
                            "
                          
                          
                            );

}


                          
                          
                            if
                          
                           (StringUtils.isBlank(ip) || 
                          
                            "
                          
                          
                            unknown
                          
                          
                            "
                          
                          
                            .equalsIgnoreCase(ip)) {

ip 
                          
                          =
                          
                             request.getRemoteAddr();

}


                          
                          
                            return
                          
                          
                             ip;

}


                          
                          
                            /*
                          
                          
                            *

* 获取当前用户


                          
                          
                            */
                          
                          
                            private
                          
                          
                             String getCurrentUsername() {

Authentication authentication 
                          
                          =
                          
                             SecurityContextHolder.getContext().getAuthentication();


                          
                          
                            if
                          
                           (authentication != 
                          
                            null
                          
                          
                            ) {


                          
                          
                            return
                          
                          
                             authentication.getName();

}


                          
                          
                            return
                          
                          
                            null
                          
                          
                            ;

}


                          
                          
                            /*
                          
                          
                            *

* 获取请求的参数


                          
                          
                            */
                          
                          
                            private
                          
                          
                             String getParams(HttpServletRequest request) {

Map
                          
                          <String, String[]> parameterMap =
                          
                             request.getParameterMap();


                          
                          
                            if
                          
                           (parameterMap == 
                          
                            null
                          
                           ||
                          
                             parameterMap.isEmpty()) {


                          
                          
                            return
                          
                          
                            null
                          
                          
                            ;

}

StringBuilder sb 
                          
                          = 
                          
                            new
                          
                          
                             StringBuilder();


                          
                          
                            for
                          
                           (Map.Entry<String, String[]>
                          
                             entry : parameterMap.entrySet()) {

sb.append(entry.getKey()).append(
                          
                          
                            "
                          
                          
                            =
                          
                          
                            "
                          
                          ).append(Arrays.toString(entry.getValue())).append(
                          
                            "
                          
                          
                            &
                          
                          
                            "
                          
                          
                            );

}


                          
                          
                            return
                          
                          
                             sb.toString();

}

}
                          
                        

使用AOP拦截日志并保存到数据库中

使用AOP技术拦截所有Controller类中的方法,并执行LogInterceptor中的preHandle方法,记录日志并保存到数据库中.

定义一个LogAspect切面类,通过实现@Aspect注解和@Before注解来实现方法拦截:

                          
                            @Aspect

@Component


                          
                          
                            public
                          
                          
                            class
                          
                          
                             LogAspect {

@Autowired


                          
                          
                            private
                          
                          
                             LogInterceptor logInterceptor;

@Pointcut(
                          
                          
                            "
                          
                          
                            execution(public * com.example.demo.controller..*.*(..))
                          
                          
                            "
                          
                          
                            )


                          
                          
                            public
                          
                          
                            void
                          
                          
                             logAspect() {}

@Before(
                          
                          
                            "
                          
                          
                            logAspect()
                          
                          
                            "
                          
                          
                            )


                          
                          
                            public
                          
                          
                            void
                          
                          
                             doBefore(JoinPoint joinPoint) {

ServletRequestAttributes attributes 
                          
                          =
                          
                             (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();


                          
                          
                            if
                          
                           (attributes == 
                          
                            null
                          
                          
                            ) {


                          
                          
                            return
                          
                          
                            ;

}

HttpServletRequest request 
                          
                          =
                          
                             attributes.getRequest();

HttpServletResponse response 
                          
                          =
                          
                             attributes.getResponse();

HandlerMethod handlerMethod 
                          
                          =
                          
                             (HandlerMethod) joinPoint.getSignature();


                          
                          
                            try
                          
                          
                             {

logInterceptor.preHandle(request, response, handlerMethod);

} 
                          
                          
                            catch
                          
                          
                             (Exception e) {

e.printStackTrace();

}

}

}
                          
                        

代码方法介绍

  • LogInterceptor.preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)方法:拦截请求并记录日志的方法。
  • LogInterceptor.getIpAddress(HttpServletRequest request)方法:获取请求的IP地址。
  • LogInterceptor.getCurrentUsername()方法:获取当前用户。
  • LogInterceptor.getParams(HttpServletRequest request)方法:获取请求的参数。
  • LogAspect.logAspect()方法:定义AOP切入点,拦截Controller类中的所有方法。
  • LogAspect.doBefore(JoinPoint joinPoint)方法:执行方法拦截操作,并调用LogInterceptor.preHandle方法来记录日志。

测试用例

可以使用Postman等工具发起请求来测试拦截器是否生效,并查看数据库中是否保存了对应的日志信息。这里就不直接演示了,毕竟使用起来非常的简单易上手.

全文小结

本文介绍了如何使用Spring Boot和AOP技术实现拦截系统日志并保存到数据库中的功能,包括配置数据库连接、定义日志实体类、定义日志拦截器、使用AOP拦截日志并保存到数据库中等步骤。通过本文的介绍,可以更好地理解Spring Boot和AOP的应用,为开发高效、稳定的系统提供参考.

注:

环境说明:Windows10 + Idea2021.3.2 + Jdk1.8 + SpringBoot 2.3.1.RELEASE 。

  。

点击关注,第一时间了解华为云新鲜技术~ 。

  。

最后此篇关于通过AOP拦截SpringBoot日志并将其存入数据库的文章就讲到这里了,如果你想了解更多关于通过AOP拦截SpringBoot日志并将其存入数据库的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com