【第17章】spring-mvc之日志和拦截器

文章目录

  • 前言
  • 一、整合log4j
    • 1. 引入库
    • 2. log4j2.xml
  • 二、拦截器
    • 1.拦截器类
    • 2.注册拦截器
  • 三、过滤器和拦截器顺序
  • 总结


前言

【第2章】整合log4j2框架

在前面的spring中已经完成了对日志框架log4j的整合,这里我们直接拿过来用就行。

场景描述:每个接口请求过来的时候,我们需要记录下请求报文和响应报文作为日志留痕或者提供给日志系统来做下一步处理的依据。


一、整合log4j

1. 引入库

<!-- log4j2 -->
<dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>2.19.0</version>
</dependency>
<dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-slf4j2-impl</artifactId><version>2.19.0</version>
</dependency>

2. log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
<!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出-->
<!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数-->
<configuration status="WARN" monitorInterval="30"><Properties><Property name="LOG_HOME">../logs/</Property><!--_TRACE_ID,业务自定义变量--><property name="ALL_PATTERN">[%d{yyyy-MM-dd HH:mm:ss.SSS}][%t][%p]- %l - %m%n</property><property name="CHARSET">UTF-8</property><property name="FILE_SIZE">1GB</property><property name="FILE_INDEX_MAX">30</property></Properties><!--先定义所有的appender--><appenders><!--这个输出控制台的配置--><console name="Console" target="SYSTEM_OUT"><!--输出日志的格式--><PatternLayout pattern="${ALL_PATTERN}"/></console><!--文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,这个也挺有用的,适合临时测试用--><File name="log" fileName="${LOG_HOME}/spring-first.log" append="false"><PatternLayout pattern="${ALL_PATTERN}"/></File><!-- 这个会打印出所有的debug及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档--><RollingFile name="RollingFileDebug" fileName="${LOG_HOME}/debug.log"filePattern="${LOG_HOME}/logs/$${date:yyyy-MM}/warn-%d{yyyy-MM-dd}-%i.log"><ThresholdFilter level="debug" onMatch="ACCEPT" onMismatch="DENY"/><PatternLayout pattern="${ALL_PATTERN}"/><Policies><TimeBasedTriggeringPolicy/><SizeBasedTriggeringPolicy size="100 MB"/></Policies><!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件,这里设置了20 --><DefaultRolloverStrategy max="20"/></RollingFile><RollingFile name="RollingFileInfo" fileName="${LOG_HOME}/info.log"filePattern="${LOG_HOME}/logs/$${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log"><!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)--><ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/><PatternLayout pattern="${ALL_PATTERN}"/><Policies><TimeBasedTriggeringPolicy/><SizeBasedTriggeringPolicy size="100 MB"/></Policies></RollingFile><RollingFile name="RollingFileError" fileName="${LOG_HOME}/error.log"filePattern="${LOG_HOME}/logs/$${date:yyyy-MM}/error-%d{yyyy-MM-dd}-%i.log"><ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/><PatternLayout pattern="${ALL_PATTERN}"/><Policies><TimeBasedTriggeringPolicy/><SizeBasedTriggeringPolicy size="100 MB"/></Policies></RollingFile></appenders><!--然后定义logger,只有定义了logger并引入的appender,appender才会生效--><loggers><logger name="org.springframework" level="DEBUG"></logger><root level="all"><appender-ref ref="Console"/><appender-ref ref="RollingFileDebug"/><appender-ref ref="RollingFileInfo"/><appender-ref ref="RollingFileError"/></root></loggers>
</configuration>

二、拦截器

1.拦截器类

package org.example.springmvc.params.controller.interceptor;import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.log4j.Log4j2;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
import java.util.Arrays;/*** Create by zjg on 2024/5/3*/
@Log4j2
public class LogInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {if(handler instanceof HandlerMethod handlerMethod){log.debug("preHandle:method[{}],parameters[{}]",handlerMethod.getMethod(),Arrays.toString(handlerMethod.getMethodParameters()));}return HandlerInterceptor.super.preHandle(request, response, handler);}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {if(handler instanceof HandlerMethod handlerMethod){log.debug("postHandle:method[{}],response[status:{}]",handlerMethod.getMethod(),response.getStatus());}HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {log.debug("afterCompletion:"+ex);HandlerInterceptor.super.afterCompletion(request, response, handler, ex);}@ControllerAdvicepublic static class SystemResponseBodyAdvice implements ResponseBodyAdvice<Object> {@Overridepublic boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {return true;}@Overridepublic Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {log.debug("beforeBodyWrite:method[{}],response[body:{}]",returnType.getMethod(),body);return body;}}
}

2.注册拦截器

package org.example.springmvc.config;import com.alibaba.fastjson2.JSONReader;
import com.alibaba.fastjson2.JSONWriter;
import com.alibaba.fastjson2.support.config.FastJsonConfig;
import com.alibaba.fastjson2.support.spring6.http.converter.FastJsonHttpMessageConverter;
import org.example.springmvc.converters.custom.RequestConverter;
import org.example.springmvc.params.controller.interceptor.LogInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;/*** Create by zjg on 2024/4/27*/
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {List<String> patterns=new ArrayList<>();patterns.add("/**");//匹配所有请求//白名单:为防止请求接口涉及到用户私密信息,禁止打印日志或者脱敏后打印处理List<String> whitelist=new ArrayList<>();whitelist.add("/hello-*");whitelist.add("/rest/*");whitelist.add("/ajax04");registry.addInterceptor(new LogInterceptor()).addPathPatterns(patterns).excludePathPatterns(whitelist);WebMvcConfigurer.super.addInterceptors(registry);}
}

三、过滤器和拦截器顺序

在这里插入图片描述

RequestFilter-before
[2024-05-04 11:06:20.104][http-nio-8080-exec-7][DEBUG]- org.springframework.core.log.LogFormatUtils.traceDebug(LogFormatUtils.java:120) - GET “/ajax01?name=%E5%BC%A0%E4%B8%89”, parameters={masked}
[2024-05-04 11:06:20.107][http-nio-8080-exec-7][DEBUG]- org.springframework.web.servlet.handler.AbstractHandlerMapping.getHandler(AbstractHandlerMapping.java:531) - Mapped to org.example.springmvc.params.controller.AjaxController#ajax01(String)
[2024-05-04 11:06:20.110][http-nio-8080-exec-7][DEBUG]- org.example.springmvc.params.controller.interceptor.LogInterceptor.preHandle(LogInterceptor.java:26) - preHandle:method[public java.lang.String org.example.springmvc.params.controller.AjaxController.ajax01(java.lang.String)],parameters[[method ‘ajax01’ parameter 0]]
张三
[2024-05-04 11:06:20.164][http-nio-8080-exec-7][DEBUG]- org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:275) - Using ‘application/json’, given [/] and supported [application/json]
[2024-05-04 11:06:20.164][http-nio-8080-exec-7][DEBUG]- org.example.springmvc.params.controller.interceptor.LogInterceptor$SystemResponseBodyAdvice.beforeBodyWrite(LogInterceptor.java:54) - beforeBodyWrite:method[public java.lang.String org.example.springmvc.params.controller.AjaxController.ajax01(java.lang.String)],response[body:张三]
[2024-05-04 11:06:20.166][http-nio-8080-exec-7][DEBUG]- org.springframework.core.log.LogFormatUtils.traceDebug(LogFormatUtils.java:120) - Writing [“张三”]
[2024-05-04 11:06:20.511][http-nio-8080-exec-7][DEBUG]- org.example.springmvc.params.controller.interceptor.LogInterceptor.postHandle(LogInterceptor.java:34) - postHandle:method[public java.lang.String org.example.springmvc.params.controller.AjaxController.ajax01(java.lang.String)],response[status:200]
[2024-05-04 11:06:20.511][http-nio-8080-exec-7][DEBUG]- org.example.springmvc.params.controller.interceptor.LogInterceptor.afterCompletion(LogInterceptor.java:41) - afterCompletion:null
[2024-05-04 11:06:20.512][http-nio-8080-exec-7][DEBUG]- org.springframework.web.servlet.FrameworkServlet.logResult(FrameworkServlet.java:1138) - Completed 200 OK
RequestFilter-after


总结

回到顶部

以下是过滤器和拦截器的主要区别,以表格形式列出:

特性过滤器(Filter)拦截器(Interceptor)
触发时机1. 请求进入容器后,但在请求进入Servlet之前进行预处理。1. 在请求到达Controller之前或响应返回视图之前进行拦截。
依赖1. 依赖于Servlet容器,是Servlet规范的一部分。1. 依赖于Spring框架,是Spring MVC的一部分。
范围1. 可以拦截请求和响应的所有内容,包括静态资源和动态资源。1. 仅能拦截请求到达Controller之前或响应返回视图之前的处理。
实现方式1. 使用Servlet规范中的Filter接口进行实现。1. 使用Spring框架提供的HandlerInterceptor接口实现。
功能1. 主要用于过滤请求和响应,如字符编码处理、安全控制、日志记录等。1. 可以进行更复杂的业务逻辑处理,如权限控制、日志记录、性能监控、事务控制等。
IOC容器访问1. 无法直接访问Spring的IOC容器中的bean。1. 可以访问Spring的IOC容器中的各个bean,并调用业务逻辑。
实现原理1. 基于回调函数。1. 基于Java的动态代理(反射)技术。
用途1. 通用性更强,可以处理所有类型的请求和响应。1. 更多地用于Spring MVC应用中的请求处理和控制。
配置1. 在web.xml文件中进行配置。1. 在Spring MVC的配置文件中进行配置,或通过注解方式。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/687482.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【iOS】frame与bounds区别

文章目录 前言framebounds两者区别size的区别总结 前言 在学习响应者链的过程中用到了frame与bounds的混用&#xff0c;这两个属性经常出现在我们的开发中&#xff0c;特别撰写一篇博客分析区别 首先&#xff0c;我们来看一下iOS特有的坐标系&#xff0c;在iOS坐标系中以左上…

LLM 可以从简单数据中学习吗?

在 10 月份的一次周会结束后&#xff0c;我提到 SFT 训练后的 Loss 曲线呈现阶梯状&#xff0c;至于为什么&#xff0c;并没有人有合理的解释&#xff0c;加上当时的重心是提升次日留存率&#xff0c;Loss 曲线呈现阶梯状与次日留存率的关系还太远&#xff0c;即使有问题&#…

Java练手项目 个人学习等选题参考

难度系数说明&#xff1a; 难度系数用来说明项目本身进行分析设计的难度 难度系数大于1的项目是非常值得反复学习的&#xff0c;从项目中成长 前言 大家好&#xff0c;我是二哈喇子&#xff0c;此博文整理了各种项目需求 要从本篇文章下的项目中学习的思路&#xff1a; 用的…

基于STM32F401RET6智能锁项目(使用库函数点灯、按键)

点灯硬件原理图 1、首先&#xff0c;我们查看一下原理图&#xff0c;找到相对应的GPIO口 LED_R低电平导通&#xff0c;LED4亮&#xff0c;所以LED_R的GPIO口需要配置一个低电平才能亮&#xff1b; LED_G低电平导通&#xff0c;LED3亮&#xff0c;所以LED_R的GPIO口需要配置一…

防爆气象仪

TH-WFB5矿山作为一个特殊的工作环境&#xff0c;其安全生产一直是重中之重。而矿山环境中的气象变化&#xff0c;如温度、湿度、风速、风向等&#xff0c;不仅直接影响矿山的日常生产活动&#xff0c;还关系到矿工的生命安全。因此&#xff0c;防爆气象仪的应用显得尤为重要。 …

陪玩系统APP小程序H5音视频社交系统陪玩系统源码,陪玩app源码,陪玩源码搭建陪玩社交系统开发(现成,可定制)线下陪玩系统项目开发搭建

线下陪玩系统项目的设计 在需求分析完成后&#xff0c;接下来进行系统设计。系统设计主要包括以下几个部分&#xff1a; 1. 数据库设计&#xff1a;根据需求分析的结果&#xff0c;设计数据库结构&#xff0c;包括用户信息表、服务信息表、订单信息表等。 2. 界面设计&#…

激光雷达:盲人世界的导航灯塔

在科技日新月异的今天&#xff0c;一项名为“蝙蝠避障”的创新成果&#xff0c;正悄然改变着盲人朋友的日常生活&#xff0c;特别是在出行这一领域&#xff0c;它的应用如同一束光&#xff0c;照亮了前行的道路。本文将深入探讨激光雷达技术对盲人的帮助&#xff0c;揭示这项高…

虚拟化技术 分离虚拟机数据流量与ESXi的流量管理

一、实验内容 为ESXi主机添加网卡通过vClient查看已添加的网卡信息为ESXi添加网络&#xff0c;创建标准交换机修改网络配置&#xff0c;实现虚拟机数据流量与ESXi的管理流量分离 二、实验主要仪器设备及材料 安装有64位Windows操作系统的台式电脑或笔记本电脑&#xff0c;建…

探索震坤行API:一键解锁高效工业用品采购新纪元!

震坤行是一家专注于工业用品的B2B电商平台&#xff0c;为企业客户提供一站式的工业用品采购服务。虽然震坤行没有直接公开通用的API接口供开发者调用&#xff0c;但通常大型企业或合作伙伴之间可以通过API进行系统集成和数据交互。以下是一个假设性的震坤行API接口调用示例与代…

如何使用 ERNIE 千帆大模型基于 Flask 搭建智能英语能力评测对话网页机器人(详细教程)

ERNIE 千帆大模型 ERNIE-3.5是一款基于深度学习技术构建的高效语言模型&#xff0c;其强大的综合能力使其在中文应用方面表现出色。相较于其他模型&#xff0c;如微软的ChatGPT&#xff0c;ERNIE-3.5不仅综合能力更强&#xff0c;而且在训练与推理效率上也更高。这使得ERNIE-3…

VBA在Excel中登录页面的应用—动态密码设置

https://mp.weixin.qq.com/s?__biz=MzkwMzY1OTIzOA==&mid=2247484420&idx=1&sn=5f98ef156cd6a784f0b1e64eed11ee42&chksm=c093af8df7e4269bdda3ed4adc37ce5f30707760ad42a2e0c6c3278ff0a0c5fcaf890016f9b5&token=1012529499&lang=zh_CN#rd 文章目录 …

Yolov8目标检测——在Android上部署Yolov8 tflite模型

1. 简介 YOLOv8 是一种用于目标检测的深度学习模型&#xff0c;它是 YOLO&#xff08;You Only Look Once&#xff09;系列的最新版本之一。YOLO 系列因其高效和准确性而在计算机视觉领域非常受欢迎&#xff0c;特别是在需要实时目标检测的应用中&#xff0c;如视频监控、自动…