spring里面内置的非常实用的工具

一 、请求数据记录

Spring Boot提供了一个内置的日志记录解决方案,通过 AbstractRequestLoggingFilter 可以记录请求的详细信息。

AbstractRequestLoggingFilter 有两个不同的实现类,我们常用的是 CommonsRequestLoggingFilter

图片

通过 CommonsRequestLoggingFilter 开发者可以自定义记录请求的参数、请求体、请求头和客户端信息。

启用方式很简单,加个配置就行了:

@Configuration
public class RequestLoggingConfig {@Beanpublic CommonsRequestLoggingFilter logFilter() {CommonsRequestLoggingFilter filter = new CommonsRequestLoggingFilter();filter.setIncludeQueryString(true);filter.setIncludePayload(true);filter.setIncludeHeaders(true);filter.setIncludeClientInfo(true);filter.setAfterMessagePrefix("REQUEST DATA-");return filter;}
}

接下来需要配置日志级别为 DEBUG,就可以详细记录请求信息:

logging.level.org.springframework.web.filter.CommonsRequestLoggingFilter=DEBUG

图片

二 、请求/响应包装器(多次获取json body参数)

在 Spring Boot 中,请求和响应包装器是用于增强原生 HttpServletRequestHttpServletResponse 对象的功能。这些包装器允许开发者在请求处理过程中拦截和修改请求和响应数据,从而实现一些特定的功能,如请求内容的缓存、修改、日志记录,以及响应内容的修改和增强。

请求包装器

  • ContentCachingRequestWrapper:这是 Spring 提供的一个请求包装器,用于缓存请求的输入流。它允许多次读取请求体,这在需要多次处理请求数据(如日志记录和业务处理)时非常有用。

响应包装器

  • ContentCachingResponseWrapper:这是 Spring 提供的一个响应包装器,用于缓存响应的输出流。它允许开发者在响应提交给客户端之前修改响应体,这在需要对响应内容进行后处理(如添加额外的头部信息、修改响应体)时非常有用。

使用场景

  1. 请求日志记录:在处理请求之前和之后记录请求的详细信息,包括请求头、请求参数和请求体。
  2. 修改请求数据:在请求到达控制器之前修改请求数据,例如添加或修改请求头。
  3. 响应内容修改:在响应发送给客户端之前修改响应内容,例如添加或修改响应头,或者对响应体进行签名。
  4. 性能测试:通过缓存请求和响应数据,可以进行性能测试,而不影响实际的网络 I/O 操作。

具体用法

请求包装器的使用
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@Component
public class RequestWrapperFilter extends OncePerRequestFilter {@Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)throws ServletException, IOException {ContentCachingRequestWrapper requestWrapper = new ContentCachingRequestWrapper(request);// 可以在这里处理请求数据byte[] body = requestWrapper.getContentAsByteArray();// 处理body,例如记录日志//。。。filterChain.doFilter(requestWrapper, response);}
}
响应包装器的使用
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@Component
public class ResponseWrapperFilter extends OncePerRequestFilter {@Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)throws ServletException, IOException {ContentCachingResponseWrapper responseWrapper = new ContentCachingResponseWrapper(response);filterChain.doFilter(request, responseWrapper);// 可以在这里处理响应数据byte[] body = responseWrapper.getContentAsByteArray();// 处理body,例如添加签名responseWrapper.setHeader("X-Signature", "some-signature");// 必须调用此方法以将响应数据发送到客户端responseWrapper.copyBodyToResponse();}
}

在上面的案例中,OncePerRequestFilter 确保过滤器在一次请求的生命周期中只被调用一次,这对于处理请求和响应数据尤为重要,因为它避免了在请求转发或包含时重复处理数据。

通过使用请求和响应包装器,开发者可以在不改变原有业务逻辑的情况下,灵活地添加或修改请求和响应的处理逻辑。

三、单次过滤器

3.1 OncePerRequestFilter

OncePerRequestFilter 是 Spring 框架提供的一个过滤器基类,它继承自 Filter 接口。这个过滤器具有以下特点:

  1. 单次执行OncePerRequestFilter 确保在一次请求的生命周期内,无论请求如何转发(forwarding)或包含(including),过滤器逻辑只执行一次。这对于避免重复处理请求或响应非常有用。
  2. 内置支持:它内置了对请求和响应包装器的支持,使得开发者可以方便地对请求和响应进行包装和处理。
  3. 简化代码:通过继承 OncePerRequestFilter,开发者可以减少重复代码,因为过滤器的执行逻辑已经由基类管理。
  4. 易于扩展:开发者可以通过重写 doFilterInternal 方法来实现自己的过滤逻辑,而不需要关心过滤器的注册和执行次数。

3.2 OncePerRequestFilter 使用场景

  1. 请求日志记录:在请求处理之前和之后记录请求的详细信息,如请求头、请求参数和请求体,而不希望在请求转发时重复记录。
  2. 请求数据修改:在请求到达控制器之前,对请求数据进行预处理或修改,例如添加或修改请求头,而不希望这些修改在请求转发时被重复应用。
  3. 响应数据修改:在响应发送给客户端之前,对响应数据进行后处理或修改,例如添加或修改响应头,而不希望这些修改在请求包含时被重复应用。
  4. 安全控制:实现安全控制逻辑,如身份验证、授权检查等,确保这些逻辑在一次请求的生命周期内只执行一次。
  5. 请求和响应的包装:使用 ContentCachingRequestWrapperContentCachingResponseWrapper 等包装器来缓存请求和响应数据,以便在请求处理过程中多次读取或修改数据。
  6. 性能监控:在请求处理前后进行性能监控,如记录处理时间,而不希望这些监控逻辑在请求转发时被重复执行。
  7. 异常处理:在请求处理过程中捕获和处理异常,确保异常处理逻辑只执行一次,即使请求被转发到其他处理器。

通过使用 OncePerRequestFilter,开发者可以确保过滤器逻辑在一次请求的生命周期内只执行一次,从而避免重复处理和潜在的性能问题。这使得 OncePerRequestFilter 成为处理复杂请求和响应逻辑时的一个非常有用的工具。

四 AOP 三件套

在 Spring 框架中,AOP(面向切面编程)是一个强大的功能,它允许开发者在不修改源代码的情况下,对程序的特定部分进行横向切入。AopContextAopUtilsReflectionUtils 是 Spring AOP 中提供的几个实用类。

我们一起来看下。

4.1 AopContext

AopContext 是 Spring 框架中的一个类,它提供了对当前 AOP 代理对象的访问,以及对目标对象的引用。

AopContext 主要用于获取当前代理对象的相关信息,以及在 AOP 代理中进行一些特定的操作。

常见方法有两个:

  • getTargetObject(): 获取当前代理的目标对象。
  • currentProxy(): 获取当前的代理对象。

其中第二个方法,在防止同一个类中注解失效的时候,可以通过该方法获取当前类的代理对象。

举个栗子:

public void noTransactionTask(String keyword){    // 注意这里 调用了代理类的方法((YourClass) AopContext.currentProxy()).transactionTask(keyword);
}@Transactional
void transactionTask(String keyword) {try {Thread.sleep(5000);} catch (InterruptedException e) {        //logger//error tracking}System.out.println(keyword);
}

同一个类中两个方法,noTransactionTask 方法调用 transactionTask 方法,为了使事务注解不失效,就可以使用 AopContext.currentProxy() 去获取当前代理对象。

4.2 AopUtils

AopUtils 提供了一些静态方法来处理与 AOP 相关的操作,如获取代理对象、获取目标对象、判断代理类型等。

常见方法有三个:

  • getTargetObject(): 从代理对象中获取目标对象。
  • isJdkDynamicProxy(Object obj): 判断是否是 JDK 动态代理。
  • isCglibProxy(Object obj): 判断是否是 CGLIB 代理。

举个栗子:

import org.springframework.aop.framework.AopProxyUtils;
import org.springframework.aop.support.AopUtils;public class AopUtilsExample {public static void main(String[] args) {MyService myService = ...// 假设 myService 已经被代理if (AopUtils.isCglibProxy(myService)) {System.out.println("这是一个 CGLIB 代理对象");}}
}

4.3 ReflectionUtils

ReflectionUtils 提供了一系列反射操作的便捷方法,如设置字段值、获取字段值、调用方法等。这些方法封装了 Java 反射 API 的复杂性,使得反射操作更加简单和安全。

常见方法:

  • makeAccessible(Field field): 使私有字段可访问。
  • getField(Field field, Object target): 获取对象的字段值。
  • invokeMethod(Method method, Object target, Object... args): 调用对象的方法。

举个栗子:

import org.springframework.util.ReflectionUtils;import java.lang.reflect.Field;
import java.util.Map;public class ReflectionUtilsExample {public static void main(String[] args) throws Exception {ExampleBean bean = new ExampleBean();bean.setMapAttribute(new HashMap<>());Field field = ReflectionUtils.findField(ExampleBean.class, "mapAttribute");ReflectionUtils.makeAccessible(field);Object value = ReflectionUtils.getField(field, bean);System.out.println(value);}static class ExampleBean {private Map<String, String> mapAttribute;public void setMapAttribute(Map<String, String> mapAttribute) {this.mapAttribute = mapAttribute;}}
}

总结 / oauth2示例

还有哪些实用内置类呢?欢迎小伙伴们留言,我会研究一下记录在博文里,同时会署名提供的朋友。

最近看到好多朋友在问oauth2的demo,我之前写过一个,不是很详细(大致功能都有)有兴趣的朋友可以参考一下。gitee地址:

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

AlDente Pro for Mac电池健康保护工具

AlDente Pro for Mac 是一款适用于 Mac 的实用电池健康保护工具。以下是它的主要特点和优势&#xff1a; 软件下载地址 一、保护电池寿命的原理 锂离子和聚合物电池&#xff08;如 Mac 笔记本中的电池&#xff09;在 30% 到 80% 之间运行时使用寿命最长。始终将电池电量保持…

网关基础知识

1.网关路由 网关&#xff1a;就是网络的关口&#xff0c;负责请求的路由、转发、身份校验。 在SpringCloud中网关的实现包括两种&#xff1a; 1.Spring Cloud Gateway Spring官方出品 基于WebFlux响应式编程 无需调优即可获得优异性能 2.Netflix Zuul Netflix出品 基于Ser…

快递物流短信API接口代码

官网&#xff1a;快递鸟 API参数 用户信息类 一.短信模版 1.接口说明 使用快递鸟短信功能时&#xff0c;预先设置好短信模板和对应的发送规则&#xff0c;快递鸟短信API将根据设置的好的模板和规则&#xff0c;进行短信的发送和反馈。 (1)仅支持Json格式。 (2)请求指令810…

vulnhub(13):Digitalworld.local JOY(ftp 的未授权文件读写漏洞、文件覆盖提权)

端口 nmap主机发现 nmap -sn 192.168.72.0/24 ​ Nmap scan report for 192.168.72.171 Host is up (0.00020s latency). ​ 171是新出现的机器&#xff0c;他就是靶机 nmap端口扫描 nmap -Pn 192.168.72.171 -p- --min-rate 10000 -oA nmap/scan 扫描开放端口保存到 nmap/sca…

Python | Leetcode Python题解之第435题无重叠区间

题目&#xff1a; 题解&#xff1a; class Solution:def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:if not intervals:return 0intervals.sort(keylambda x: x[1])n len(intervals)right intervals[0][1]ans 1for i in range(1, n):if intervals…

网络资源模板--Android Studio 垃圾分类App

目录 一、项目演示 二、项目测试环境 三、项目详情 四、完整的项目源码 一、项目演示 网络资源模板--垃圾分类App 二、项目测试环境 三、项目详情 登陆注册 设置点击监听器&#xff1a;当用户点击注册按钮时触发事件。获取用户输入&#xff1a;从输入框获取用户名和密码&a…

springboot 接口接收及响应xml数据

1.实体类 import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement;XmlRootElement XmlAccessorType(XmlAccessType.FIELD) // …

【SpringBoot详细教程】-03-整合Junit【持续更新】

JUnit是一个用于Java编程语言的测试框架。它支持自动化单元测试&#xff0c;可以帮助开发人员测试代码的正确性和健壮性。JUnit提供了一组注解、断言和测试运行器&#xff0c;可以方便地编写和运行单元测试。 SpringBoot 整合 junit 特别简单&#xff0c;分为以下三步完成 在…

网络安全等级保护 | 规范企业网络系统安全使用 | 天锐股份助力等保制度落地

在当今数字化高速发展的时代&#xff0c;网络安全对于企业的重要性日益凸显。而近年来&#xff0c;数据泄露、网络攻击等安全事件频发&#xff0c;给企业和个人带来了前所未有的挑战。在这一背景下&#xff0c;网络安全等级保护制度&#xff08;简称“等保”&#xff09;作为国…

经颅磁刺激技术,脑科学研究——精神患者治疗方案

经颅磁刺激&#xff08;Transcranial Magnetic Stimulation &#xff0c;TMS&#xff09;技术是一种利用脉冲磁场作用于中枢神经系统&#xff08;主要是大脑&#xff09;&#xff0c;改变皮层神经细胞的膜电位&#xff0c;使之产生感应电流&#xff0c;影响脑内代谢和神经电活动…

Qt QFileDialog使用方法

头文件 #include <QFileDialog> 成员名称返回值说明getExistingDirectoryQString返回用户选中的文件夹路径getExistingDirectoryUrlQUrl与QFileDialog::getExistingDirectory()的主要区别来自于为用户提供的选择远程目录的能力getOpenFileNameQString返回用户选中的文件…

基于深度学习的树叶识别系统的设计与实现(pyqt5 python3.9 yolov8 10000张数据集)

&#x1f497;博主介绍&#x1f497;&#xff1a;✌在职Java研发工程师、专注于程序设计、源码分享、技术交流、专注于Java技术领域和毕业设计✌ 温馨提示&#xff1a;文末有 CSDN 平台官方提供的老师 Wechat / QQ 名片 :) Java精品实战案例《700套》 2025最新毕业设计选题推荐…

解锁微软录屏工具:2024 开启屏幕录制新时代

现在快节奏的生活环境&#xff0c;录屏工具已成为不可或缺的记录利器&#xff0c;其应用范围广泛。若你正对windows自带录屏功能充满好奇&#xff0c;渴望掌握其操作方法&#xff0c;或是寻求更多专业、便捷的录屏软件选项&#xff0c;那么就请继续阅读吧。 1.福昕录屏大师 链…

Figma 中要放大并下载 UI 设计中的图标

Figma 中要放大并下载 UI 设计中的图标&#xff0c;通常可以通过以下几步操作来实现&#xff1a; 1. 放大图标&#xff1a; 打开 Figma 文件并找到你想要放大的图标。 选中图标&#xff0c;点击界面右上角的 “缩放”工具&#xff08;放大镜图标&#xff09;&#xff0…

Note_XML学习笔记

XML学习笔记 1. XML 教程 经常见到XML学习一下。由于是学到中间才想起记笔记&#xff0c;之前的就简略回顾一下&#xff1a; 1&#xff09;XML是数据存储的一种语言载体&#xff1b; 2&#xff09;只负责存储&#xff0c;不负责显示&#xff1b; 3&#xff09;和HTML语言的风…

华为认证HCIA篇--网络通信基础

大家好呀&#xff01;我是reload。今天来带大家学习一下华为认证ia篇的网络通信基础部分&#xff0c;偏重一些基础的认识和概念性的东西。如果对网络通信熟悉的小伙伴可以选择跳过&#xff0c;如果是新手或小白的话建议还是看一看&#xff0c;先有个印象&#xff0c;好为后续的…

【德国RapidEye地球探测卫星】

德国RapidEye地球探测卫星 德国RapidEye地球探测卫星是一项具有重要意义的商业遥感卫星系统&#xff0c;以下是关于该卫星的详细介绍&#xff1a; 一、基本概况 名称&#xff1a;RapidEye性质&#xff1a;商用卫星发射时间&#xff1a;2008年8月29日&#xff0c;由第聂伯-1…

Spring AOP实现原理-动态代理

目录 代理的基础概念 示例1&#xff1a;静态代理&#xff08;场景&#xff1a;客户通过中介租房东的房子&#xff09; 示例2&#xff1a;JDK动态代理实现房东、中介出租房屋 示例3&#xff1a;CGLib动态代理实现房东出租房屋 示例4&#xff1a;观察Spring IOC容器中代理对象…

HDFS_API文件详情查看

代码&#xff1a; private FileSystem fs;Beforepublic void init() throws URISyntaxException, IOException {URI uri new URI("hdfs://master:9000");// 创建一个配置文件Configuration entries new Configuration();// 获取到了客户端对象 // entries.…

科研绘图系列:R语言分组堆积图(stacked barplot)

文章目录 介绍加载R包导入数据数据预处理画图导出数据系统信息介绍 堆积图是一种数据可视化图表,它通过将不同类别的数据以堆叠的形式展现在同一个图表中,来展示各个类别之间的相对大小和它们之间的总和。堆积图可以是柱状图、条形图或面积图的形式,其中每个堆叠的块或区域…