springBoot 使用 AOP 拦截请求日志信息

添加依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.3.5</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>RELEASE</version>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

        <!-- 解析 UserAgent 信息 -->
        <dependency>
            <groupId>eu.bitwalker</groupId>
            <artifactId>UserAgentUtils</artifactId>
            <version>1.21</version>
        </dependency>

创建AOP类

注意修改切入点包扫描路径

@Aspect
@Component
@Slf4j
public class AopLog {
	private static final String START_TIME = "request-start";

	/**
	 * 切入点
	 */
	@Pointcut("execution(public * com.my.codetest.controller.*Controller.*(..))")
	public void log() {

	}

	/**
	 * 前置操作
	 *
	 * @param point 切入点
	 */
	@Before("log()")
	public void beforeLog(JoinPoint point) {
		ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();

		HttpServletRequest request = Objects.requireNonNull(attributes).getRequest();

		log.info("【请求 URL】:{}", request.getRequestURL());
		log.info("【请求 IP】:{}", request.getRemoteAddr());
		log.info("【请求类名】:{},【请求方法名】:{}", point.getSignature().getDeclaringTypeName(), point.getSignature().getName());

		Map<String, String[]> parameterMap = request.getParameterMap();
		log.info("【请求参数】:{},", JSONUtil.toJsonStr(parameterMap));
		Long start = System.currentTimeMillis();
		request.setAttribute(START_TIME, start);
	}

	/**
	 * 环绕操作
	 *
	 * @param point 切入点
	 * @return 原方法返回值
	 * @throws Throwable 异常信息
	 */
	@Around("log()")
	public Object aroundLog(ProceedingJoinPoint point) throws Throwable {
		Object result = point.proceed();
		log.info("【返回值】:{}", JSONUtil.toJsonStr(result));
		return result;
	}

	/**
	 * 后置操作
	 */
	@AfterReturning("log()")
	public void afterReturning() {
		ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
		HttpServletRequest request = Objects.requireNonNull(attributes).getRequest();

		Long start = (Long) request.getAttribute(START_TIME);
		Long end = System.currentTimeMillis();
		log.info("【请求耗时】:{}毫秒", end - start);

		String header = request.getHeader("User-Agent");
		UserAgent userAgent = UserAgent.parseUserAgentString(header);
		log.info("【浏览器类型】:{},【操作系统】:{},【原始User-Agent】:{}", userAgent.getBrowser().toString(), userAgent.getOperatingSystem().toString(), header);
	}
}

调用接口查看结果

在这里插入图片描述

结合 logback

详情请看这篇 快速集成logback日志

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: Spring Boot AOP可以用来拦截Controller中的方法,实现请求的统一处理。通过定义切面和切点,可以在请求前、后、异常等不同的阶段进行处理,比如记录日志、权限校验、参数校验等。在Spring Boot中,可以使用@Aspect注解定义切面,使用@Pointcut注解定义切点,使用@Before、@After、@Around等注解定义不同类型的通知。同时,还可以使用@Order注解指定切面的执行顺序。 ### 回答2: 在Web应用中,Controller是连接前端和后端的重要部分,用于处理请求和响应返回数据。在某些情况下,我们需要对Controller进一步处理,例如记录请求日志、验证权限、异常处理等。这就需要用到SpringBoot AOP进行拦截SpringBoot AOP是一种面向切面的编程方式,通过拦截目标方法,插入特定的处理逻辑来增强系统功能。在Controller上使用AOP进行拦截可以帮助我们方便的实现业务逻辑,避免重复代码。 实现步骤如下: 1. 创建一个自定义注解,用于标记要拦截的Controller方法。 ``` @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface LogRecord { String value() default ""; } ``` 2. 在拦截器中定义具体的切面逻辑,例如记录请求日志、验证权限等。 ``` @Component @Aspect public class ControllerInterceptor { @Autowired private HttpServletRequest request; private static final Logger logger = LoggerFactory.getLogger(ControllerInterceptor.class); @Around("@annotation(com.example.demo.annotations.LogRecord)") public Object recordLog(ProceedingJoinPoint joinPoint) throws Throwable { ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); String methodName = joinPoint.getSignature().getName(); String className = joinPoint.getTarget().getClass().getSimpleName(); logger.info("请求路径:{},请求参数:{},请求方法:{}.{}", request.getRequestURI(), JsonUtil.toJSONString(request.getParameterMap()), className, methodName); Object result = joinPoint.proceed(); return result; } } ``` 3. 在Controller方法上标注自定义注解,使其成为切面的切点。 ``` @RestController @RequestMapping("/demo") public class DemoController { @Autowired private UserService userService; @RequestMapping(value = "/getUserById", method = RequestMethod.GET) @LogRecord public ResponseEntity<?> getUserById(@RequestParam("id") String id) { User user = userService.getUserById(id); return ResponseEntity.ok(user); } } ``` 4. 在SpringBoot主类上使用@EnableAspectJAutoProxy注解开启代理自动配置。 ``` @SpringBootApplication @EnableAspectJAutoProxy public class MyApplication { public static void main(String[] args) { SpringApplication.run(MyApplication.class, args); } } ``` 以上就是使用SpringBoot AOP进行Controller拦截的步骤,通过自定义注解和拦截器的方式,我们可以方便的实现各种Controller拦截逻辑,提升Web应用的可维护性和可扩展性。 ### 回答3: Spring Boot AOP(面向切面编程)是Spring Framework的一个重要部分,它允许我们在程序中实现横切关注点的模块化。横切关注点是一个横跨不同模块和层的功能,如日志、安全性、事务管理等,这些功能在整个程序中多次出现,从而导致代码不需要重复编写。在Spring Boot中,我们可以使用AOP实现一些特定的横切关注点,例如:拦截Controller请求。 在Spring Boot中,拦截Controller请求是很常见的需求,这是因为我们需要对请求进行验证、权限控制和日志记录等。使用AOP拦截Controller请求的过程中,我们需要定义一个Aspect切面,切入到Controller的请求中执行某些操作。 下面是实现Spring Boot使用AOP拦截Controller请求的步骤: 1. 定义一个Aspect切面: @Component @Aspect public class MyAspect { @Pointcut("execution(public * com.example.controller.*.*(..))") public void controllerPointcut() {} @Before("controllerPointcut()") public void beforeControllerMethod(JoinPoint jp) { //执行请求前的逻辑 } @AfterReturning(pointcut="controllerPointcut()", returning="result") public void afterControllerMethod(JoinPoint jp, Object result) { //执行请求后的逻辑 } } 2. 在切面中定义一个Pointcut,用来指定需要拦截请求。上面的例子中,我们使用execution表达式指定了com.example.controller包下所有public方法为切入点。 3. 在切面中定义拦截Controller请求时需要执行的操作。我们可以在@Before注解中定义请求进入前的逻辑,在@AfterReturning注解中定义请求结束后的逻辑。 4. 在Controller类中注入我们定义的切面,即可使用AOP拦截Controller请求。 @Controller public class MyController { @Autowired private MyAspect myAspect; @GetMapping("/test") public String test() { //请求逻辑 return "test"; } } 通过以上步骤,我们就可以在Spring Boot使用AOP拦截Controller请求了。需要注意的是,在AOP中定义的逻辑需要足够简洁,并且避免阻塞请求。此外,对于业务逻辑中存在事务的Controller方法不建议使用AOP拦截,因为AOP会改变事务管理的行为。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Dotclv

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值