Spring Boot的实用内置功能详解
Spring Boot作为一款备受欢迎的Java框架,以其简洁、高效和易用的特点,赢得了广大开发者的青睐。其内置的多种功能更是为开发者提供了极大的便利,本文将详细介绍Spring Boot中记录请求数据、请求/响应包装器、特殊的过滤器Filter以及Controller接口定义等实用内置功能。
一、记录请求数据
在Spring Boot中,记录请求数据是一项非常重要的功能,它有助于开发者在调试和监控应用程序时,获取详尽的请求信息。Spring Boot提供了多种方式来记录请求数据,其中利用AOP(面向切面编程)和过滤器Filter是比较常见的两种方式。
-
利用AOP记录请求数据
AOP允许开发者在方法执行的前后添加额外的逻辑,而不需要修改方法本身的代码。在Spring Boot中,可以利用AOP切面来拦截Controller层的方法,从而记录请求数据。
定义一个切面类,该类包含前置通知(在方法执行前记录请求数据)和后置通知(在方法执行后记录响应数据)。通过注解
@Aspect
和@Component
将该切面类注册为Spring容器中的一个Bean。在切面类中,使用@Pointcut
注解定义切入点表达式,用于匹配需要拦截的方法。然后,使用@Before
和@AfterReturning
注解分别定义前置通知和后置通知的逻辑。 -
利用过滤器Filter记录请求数据
过滤器Filter是Servlet规范中的一部分,它允许开发者在请求到达Servlet之前或响应发送给客户端之前对请求和响应进行预处理和后处理。在Spring Boot中,可以通过实现
javax.servlet.Filter
接口来创建自定义的过滤器。在过滤器类中,重写
doFilter
方法,在该方法中实现日志记录逻辑。可以从ServletRequest
和ServletResponse
对象中获取请求和响应的详细信息,如请求URL、请求参数、请求头、响应状态码等。然后,使用日志框架(如Logback或Log4j)将这些信息记录到日志文件中。此外,Spring Boot还提供了
AbstractRequestLoggingFilter
和CommonsRequestLoggingFilter
等内置过滤器,用于记录请求数据。这些过滤器可以通过简单的配置即可使用,无需编写额外的代码。
二、请求/响应包装器
请求/响应包装器是Spring Boot另一个强大的功能,它允许开发者在请求处理过程中增强HttpServletRequest和HttpServletResponse的功能。通过包装器,开发者可以在不修改原始请求和响应对象的情况下,添加额外的逻辑或信息。
-
请求包装器
使用
ContentCachingRequestWrapper
可以对请求内容进行缓存,使得同一请求可以多次读取。这在记录日志或数据修改时非常有用。例如,当需要记录请求体中的JSON数据时,可以使用请求包装器来缓存请求体,并在日志记录完成后继续处理请求。 -
响应包装器
使用
ContentCachingResponseWrapper
可以对响应内容进行缓存和修改。通过包装器,开发者可以在最终响应之前修改响应头、响应体或添加额外的信息。这对于实现响应的压缩、加密或添加自定义的响应头等功能非常有帮助。
三、特殊的过滤器Filter
除了上述提到的记录请求数据的过滤器外,Spring Boot还支持多种特殊的过滤器,用于实现不同的功能。
-
OncePerRequestFilter
OncePerRequestFilter
是Spring框架中的一个重要过滤器基类,它确保过滤器逻辑在请求的生命周期中只被执行一次。无论请求如何转发或包含,这种机制都能极大地减少重复处理的风险,确保请求数据处理的高效性。 -
AbstractPreAuthenticatedProcessingFilter
AbstractPreAuthenticatedProcessingFilter
是一个用于预认证处理的过滤器基类。它允许开发者在请求到达应用程序之前,通过某种方式(如HTTP头、SSL会话等)进行用户的预认证。这对于实现基于令牌的身份验证或单点登录等功能非常有用。 -
其他自定义过滤器
开发者还可以根据自己的需求创建自定义的过滤器。通过实现
javax.servlet.Filter
接口或继承Spring Boot提供的过滤器基类(如OncePerRequestFilter
),可以轻松地创建具有特定功能的过滤器。
四、Controller接口定义
在Spring Boot中,Controller层负责处理HTTP请求并返回响应。Spring Boot提供了多种方式来定义Controller接口,以满足不同的需求。
-
使用
@RestController
注解@RestController
是一个组合注解,它结合了@Controller
和@ResponseBody
的功能。使用@RestController
注解的类中的所有方法都会默认返回JSON或XML格式的响应体。这对于实现RESTful API非常有用。 -
使用
@RequestMapping
注解@RequestMapping
注解用于将HTTP请求映射到特定的处理方法上。它可以定义在类或方法级别上,用于匹配请求的URL、请求方法(如GET、POST等)、请求参数等。通过@RequestMapping
注解,开发者可以灵活地定义Controller接口的处理逻辑。 -
使用
@GetMapping
、@PostMapping
等衍生注解Spring Boot还提供了
@GetMapping
、@PostMapping
、@PutMapping
、@DeleteMapping
等衍生注解,用于简化@RequestMapping
注解的配置。这些衍生注解分别用于匹配特定的HTTP请求方法,使得代码更加简洁易读。 -
使用
@RequestBody
和@ResponseBody
注解@RequestBody
注解用于将HTTP请求体中的内容绑定到方法参数上,通常用于处理POST请求中的JSON或XML数据。@ResponseBody
注解用于将方法的返回值直接写入HTTP响应体中,通常用于返回JSON或XML格式的响应数据。
综上所述,Spring Boot的内置功能为开发者提供了极大的便利和灵活性。通过记录请求数据、使用请求/响应包装器、配置特殊的过滤器以及灵活定义Controller接口等方式,开发者可以轻松地构建高效、可靠和易于维护的Web应用程序。
五、例子
1. 日志记录
Spring Boot提供了一个内置的日志记录解决方案,通过AbstractRequestLoggingFilter
可以记录请求的详细信息。例如,使用CommonsRequestLoggingFilter
来记录请求的参数、请求体、请求头和客户端信息:
@Configuration
public class RequestLoggingConfig { @Bean public 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
2. 过滤器(Filter)
过滤器可以用于对请求和响应进行预处理和后处理。例如,可以创建一个自定义过滤器来记录请求的URL:
package com.example.filter; import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException; public class MyFilter implements Filter { @Override public void init(javax.servlet.FilterConfig filterConfig) throws ServletException { // 过滤器初始化逻辑 } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { if (servletRequest instanceof HttpServletRequest) { System.out.println("URL: " + ((HttpServletRequest) servletRequest).getRequestURL()); } // 调用过滤器链中的下一个过滤器 filterChain.doFilter(servletRequest, servletResponse); } @Override public void destroy() { // 过滤器销毁逻辑 }
}
然后,使用FilterRegistrationBean
来注册这个自定义过滤器:
@Configuration
public class FilterConfig { @Bean public FilterRegistrationBean registrationBean() { FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new MyFilter()); filterRegistrationBean.addUrlPatterns("/*"); return filterRegistrationBean; }
}
3. 控制器(Controller)定义
在Spring Boot中,控制器通常使用@RestController
注解来定义。这个注解是@Controller
和@ResponseBody
的组合,表示该类可以处理HTTP请求,并且返回值会自动序列化为JSON格式。
例如,定义一个简单的用户控制器:
@RestController
@RequestMapping("/users")
public class UserController { @GetMapping("/{id}") public User getUserById(@PathVariable Long id) { // 假设这里有一个服务层来获取用户信息 return new User(id, "用户名" + id); } @PostMapping public ResponseEntity<User> createUser(@RequestBody User user) { // 假设这里有一个服务层来创建用户 return ResponseEntity.ok(user); }
}
其中,User
类是一个简单的POJO类,包含用户的ID和用户名等信息。
4. 请求和响应处理
Spring Boot提供了请求和响应包装器(HttpServletRequestWrapper
和HttpServletResponseWrapper
),用于增强原生HttpServletRequest
和HttpServletResponse
对象的功能。例如,可以使用ContentCachingRequestWrapper
来缓存请求体,以便多次读取:
@Component
public class RequestWrapperFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { ContentCachingRequestWrapper requestWrapper = new ContentCachingRequestWrapper(request); // 可以在这里处理请求数据 byte[] body = requestWrapper.getContentAsByteArray(); // ... filterChain.doFilter(requestWrapper, response); }
}
同样地,可以使用ContentCachingResponseWrapper
来缓存响应体,以便在响应提交给客户端之前进行修改:
@Component
public class ResponseWrapperFilter extends OncePerRequestFilter { @Override protected 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(); }
}
这些例子展示了Spring Boot中的一些关键功能和概念。通过实践这些例子,您可以更好地理解Spring Boot的工作原理,并为您的项目开发提供有用的参考。
相关文章:
Spring Boot的实用内置功能详解
Spring Boot作为一款备受欢迎的Java框架,以其简洁、高效和易用的特点,赢得了广大开发者的青睐。其内置的多种功能更是为开发者提供了极大的便利,本文将详细介绍Spring Boot中记录请求数据、请求/响应包装器、特殊的过滤器Filter以及Controlle…...

撸猫变梳毛?怎么解决猫咪掉毛问题?好用的宠物空气净化器推荐
秋风一吹,新一轮的猫咪换毛季又到了,这也意味着我失去了撸猫自由。我每天的治愈方式就是下班撸猫,抚摸着柔软的毛发,好像一天的烦恼都消除了。可是一到换毛季,猫还没撸两下,先从猫咪身上带下一手毛…...

人声分离免费软件,六款好用软件处理音乐更轻松!
在这个数字化音乐时代,无论是专业音乐人还是音乐爱好者,都渴望在创作与编辑过程中拥有更多便捷高效的工具。人声分离技术,作为音乐后期制作中的一项关键技术,能够精准地将歌曲中的人声与伴奏分离,极大地拓宽了音乐创作…...

数据分析Power BI设置万为单位的数据
玩过Power BI的同学都知道,power BI在度量值设置单位里,唯独没有万这个单位,但是我们可以自定义,操作过程如下: 1.用DAX新建单位表 单位 SELECTCOLUMNS( { ( "元", 1), ("万",10000), ("千…...

(AI 生成) 新时代游击方式: 利用 “灵活就业“ 红利
注意: 本文内容为 AI 大模型生成, 仅供参考. 提示词: 写一篇短文, 500 字左右, 标题为: 新时代游击方式: 利用 “灵活就业” 红利 1 豆包 《新时代游击方式:利用“灵活就业”红利》 在新时代的大舞台上,“灵活就业”犹如一块熠熠生辉的宝藏,…...

Unity UndoRedo(撤销重做)功能
需求 撤销与重做功能 思考 关于记录的数据的两点思考: 记录操作记录影响显示和逻辑的所有数据 很显然这里就要考虑取舍了: 记录操作 这种方案只需要记录每一步的操作,具体这个操作要怎么渲染和实现出来完全需要自己去实现,这…...

28条有关人工智能的名言
当谈到人工智能(AI)的潜力和潜在风险,以及无人类干预的机器学习和推理过程时,目前尚存在许多不同的观点。 只有时间会告诉我们,这些语录中哪一条是最接近未来的真实情况的。在我们尚未到达目的地之前,想一想…...
搞机器视觉项目看不起搞机器视觉培训的,实际上怎么样
搞机器视觉项目第一要务就是验收回款,往往欠款的非常严重,多数还要打通人际关系需要大量的成本。大多数机器视觉检测项目具有一定的风险,客户要求不明确,技术评估不充分,往往伴随着失败的可能性。所以做项目又累又担风…...

使用Jenkins部署项目
部署中的痛点 为什么要用Jenkins?我说下我以前开发的痛点,在一些中小型企业,每次开发一个项目完成后,需要打包部署,可能没有专门的运维人员,只能开发人员去把项目打成一个exe包,可能这个项目已…...
【机器学习与神经网络荣获诺贝尔奖】科学边界的扩展及技术革新
【机器学习与神经网络荣获诺贝尔奖】科学边界的扩展及技术革新 1)科学交叉融合的体现2)方法论的创新3)社会影响的考量 一、机器学习与神经网络的发展前景1)生产制造领域2)金融领域3)医疗领域 二、机器学习和…...
Javascript扩展符号(...)使用说明
在 ES6 中,扩展运算符(spread operator)... 可以用于在函数调用、数组字面量或对象字面量中展开数组或对象。以下是扩展运算符的一些常见用法: 1. 在函数调用中使用扩展运算符 扩展运算符可以在函数调用时展开数组或对象&#x…...

giugughk
c语言中的小小白-CSDN博客c语言中的小小白关注算法,c,c语言,贪心算法,链表,mysql,动态规划,后端,线性回归,数据结构,排序算法领域.https://blog.csdn.net/bhbcdxb123?spm1001.2014.3001.5343 给大家分享一句我很喜欢我话: 知不足而奋进,望远山而前行&am…...

【微服务】网关 - Gateway(下)(day8)
网关过滤工厂 在上一篇文章中,主要是对网关进行了一个总体的介绍,然后对网关中的断言进行了一个描述。在这篇文章中,主要是对网关中的最后一大核心——过滤进行介绍。 当客户端发送过来的请求经过断言之后,如果还想在请求前后添…...

【C#】创建一个控制台应用程序来管理学生成绩
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 在C#中创建一个控制台应用程序来管理学生成绩编写程序程序解释 在C#中创建一个控制台应用程序来管理学生成绩 在这篇文章中,我将向你展示如何使用C#创建…...

鸿蒙开发之ArkUI 界面篇 三十四 容器组件Tabs 自定义TabBar
如果需要修改Tabs的图标和文字之间的距离我们该怎么办呢?好在tabBar是联合类型,提供了自定义tabBar,这里就可以显示特殊图标或者是文字图片,如下图: 这里定义了myBuilder的函数,用了 来修饰,没有…...

AI核身-金融场景凭证篡改检测YOLO原理
引言 YOLO (You Only Look Once) 模型是一种先进的实时目标检测算法,它在计算机视觉领域具有重要的地位。YOLO以其速度和准确性而闻名,能够快速识别图像和视频中的各种物体。这使得它在自动驾驶、安全监控、机器人技术、医学影像分析等众多领域都有着广…...
鹅厂JS面试题——0.1+0.2=0.3吗?
首先公布答案:在JavaScript 中,0.1 0.2 ≠ 0.3 为什么? JavaScript 中的数字使用 IEEE 754 标准的双精度浮点数(64 位)进行表示。这种表示方式在处理十进制小数时,不能精确地表示某些数字。比如0.1 和 0.2 这样的十进…...

软件功能测试重点和流程有哪些?专业软件测评服务公司推荐
软件功能测试就是对产品的各功能进行验证,根据功能测试用例,逐项测试,检查产品是否达到用户要求的功能。功能测试也叫黑盒测试或数据驱动测试,只需考虑需要测试的各个功能,不需要考虑整个软件的内部结构及代码.一般从软…...

【数据结构】AVL树(C++实现)
文章目录 前言AVL树节点的定义AVL树的插入AVL树的旋转AVL树的验证AVL树的删除AVL树的性能与源码 前言 二叉搜索树虽可以缩短查找的效率,但如果数据有序或接近有序二叉搜索树将退化为单支树,查找元素相当于在顺序表中搜索元素,效率低下。因此&…...

AMD新推EPYC与MI325X,挑战英伟达AI市场地位
在人工智能(AI)加速器领域,AMD近日于美国旧金山举办的“推进人工智能”(Advancing AI Event)活动中,宣布了一系列新产品的发布,直接对标英伟达,意图在AI芯片市场占据更大份额。 AMD新…...
java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别
UnsatisfiedLinkError 在对接硬件设备中,我们会遇到使用 java 调用 dll文件 的情况,此时大概率出现UnsatisfiedLinkError链接错误,原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用,结果 dll 未实现 JNI 协…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...

如何在网页里填写 PDF 表格?
有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据ÿ…...
#Uniapp篇:chrome调试unapp适配
chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器:Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...
【Go语言基础【12】】指针:声明、取地址、解引用
文章目录 零、概述:指针 vs. 引用(类比其他语言)一、指针基础概念二、指针声明与初始化三、指针操作符1. &:取地址(拿到内存地址)2. *:解引用(拿到值) 四、空指针&am…...

Web后端基础(基础知识)
BS架构:Browser/Server,浏览器/服务器架构模式。客户端只需要浏览器,应用程序的逻辑和数据都存储在服务端。 优点:维护方便缺点:体验一般 CS架构:Client/Server,客户端/服务器架构模式。需要单独…...

【p2p、分布式,区块链笔记 MESH】Bluetooth蓝牙通信 BLE Mesh协议的拓扑结构 定向转发机制
目录 节点的功能承载层(GATT/Adv)局限性: 拓扑关系定向转发机制定向转发意义 CG 节点的功能 节点的功能由节点支持的特性和功能决定。所有节点都能够发送和接收网格消息。节点还可以选择支持一个或多个附加功能,如 Configuration …...

windows系统MySQL安装文档
概览:本文讨论了MySQL的安装、使用过程中涉及的解压、配置、初始化、注册服务、启动、修改密码、登录、退出以及卸载等相关内容,为学习者提供全面的操作指导。关键要点包括: 解压 :下载完成后解压压缩包,得到MySQL 8.…...
libfmt: 现代C++的格式化工具库介绍与酷炫功能
libfmt: 现代C的格式化工具库介绍与酷炫功能 libfmt 是一个开源的C格式化库,提供了高效、安全的文本格式化功能,是C20中引入的std::format的基础实现。它比传统的printf和iostream更安全、更灵活、性能更好。 基本介绍 主要特点 类型安全:…...

Android写一个捕获全局异常的工具类
项目开发和实际运行过程中难免会遇到异常发生,系统提供了一个可以捕获全局异常的工具Uncaughtexceptionhandler,它是Thread的子类(就是package java.lang;里线程的Thread)。本文将利用它将设备信息、报错信息以及错误的发生时间都…...