当前位置: 首页 > news >正文

Spring Boot的实用内置功能详解

Spring Boot作为一款备受欢迎的Java框架,以其简洁、高效和易用的特点,赢得了广大开发者的青睐。其内置的多种功能更是为开发者提供了极大的便利,本文将详细介绍Spring Boot中记录请求数据、请求/响应包装器、特殊的过滤器Filter以及Controller接口定义等实用内置功能。

一、记录请求数据

在Spring Boot中,记录请求数据是一项非常重要的功能,它有助于开发者在调试和监控应用程序时,获取详尽的请求信息。Spring Boot提供了多种方式来记录请求数据,其中利用AOP(面向切面编程)和过滤器Filter是比较常见的两种方式。

  1. 利用AOP记录请求数据

    AOP允许开发者在方法执行的前后添加额外的逻辑,而不需要修改方法本身的代码。在Spring Boot中,可以利用AOP切面来拦截Controller层的方法,从而记录请求数据。

    定义一个切面类,该类包含前置通知(在方法执行前记录请求数据)和后置通知(在方法执行后记录响应数据)。通过注解@Aspect@Component将该切面类注册为Spring容器中的一个Bean。在切面类中,使用@Pointcut注解定义切入点表达式,用于匹配需要拦截的方法。然后,使用@Before@AfterReturning注解分别定义前置通知和后置通知的逻辑。

  2. 利用过滤器Filter记录请求数据

    过滤器Filter是Servlet规范中的一部分,它允许开发者在请求到达Servlet之前或响应发送给客户端之前对请求和响应进行预处理和后处理。在Spring Boot中,可以通过实现javax.servlet.Filter接口来创建自定义的过滤器。

    在过滤器类中,重写doFilter方法,在该方法中实现日志记录逻辑。可以从ServletRequestServletResponse对象中获取请求和响应的详细信息,如请求URL、请求参数、请求头、响应状态码等。然后,使用日志框架(如Logback或Log4j)将这些信息记录到日志文件中。

    此外,Spring Boot还提供了AbstractRequestLoggingFilterCommonsRequestLoggingFilter等内置过滤器,用于记录请求数据。这些过滤器可以通过简单的配置即可使用,无需编写额外的代码。

二、请求/响应包装器

请求/响应包装器是Spring Boot另一个强大的功能,它允许开发者在请求处理过程中增强HttpServletRequest和HttpServletResponse的功能。通过包装器,开发者可以在不修改原始请求和响应对象的情况下,添加额外的逻辑或信息。

  1. 请求包装器

    使用ContentCachingRequestWrapper可以对请求内容进行缓存,使得同一请求可以多次读取。这在记录日志或数据修改时非常有用。例如,当需要记录请求体中的JSON数据时,可以使用请求包装器来缓存请求体,并在日志记录完成后继续处理请求。

  2. 响应包装器

    使用ContentCachingResponseWrapper可以对响应内容进行缓存和修改。通过包装器,开发者可以在最终响应之前修改响应头、响应体或添加额外的信息。这对于实现响应的压缩、加密或添加自定义的响应头等功能非常有帮助。

三、特殊的过滤器Filter

除了上述提到的记录请求数据的过滤器外,Spring Boot还支持多种特殊的过滤器,用于实现不同的功能。

  1. OncePerRequestFilter

    OncePerRequestFilter是Spring框架中的一个重要过滤器基类,它确保过滤器逻辑在请求的生命周期中只被执行一次。无论请求如何转发或包含,这种机制都能极大地减少重复处理的风险,确保请求数据处理的高效性。

  2. AbstractPreAuthenticatedProcessingFilter

    AbstractPreAuthenticatedProcessingFilter是一个用于预认证处理的过滤器基类。它允许开发者在请求到达应用程序之前,通过某种方式(如HTTP头、SSL会话等)进行用户的预认证。这对于实现基于令牌的身份验证或单点登录等功能非常有用。

  3. 其他自定义过滤器

    开发者还可以根据自己的需求创建自定义的过滤器。通过实现javax.servlet.Filter接口或继承Spring Boot提供的过滤器基类(如OncePerRequestFilter),可以轻松地创建具有特定功能的过滤器。

四、Controller接口定义

在Spring Boot中,Controller层负责处理HTTP请求并返回响应。Spring Boot提供了多种方式来定义Controller接口,以满足不同的需求。

  1. 使用@RestController注解

    @RestController是一个组合注解,它结合了@Controller@ResponseBody的功能。使用@RestController注解的类中的所有方法都会默认返回JSON或XML格式的响应体。这对于实现RESTful API非常有用。

  2. 使用@RequestMapping注解

    @RequestMapping注解用于将HTTP请求映射到特定的处理方法上。它可以定义在类或方法级别上,用于匹配请求的URL、请求方法(如GET、POST等)、请求参数等。通过@RequestMapping注解,开发者可以灵活地定义Controller接口的处理逻辑。

  3. 使用@GetMapping@PostMapping等衍生注解

    Spring Boot还提供了@GetMapping@PostMapping@PutMapping@DeleteMapping等衍生注解,用于简化@RequestMapping注解的配置。这些衍生注解分别用于匹配特定的HTTP请求方法,使得代码更加简洁易读。

  4. 使用@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提供了请求和响应包装器(HttpServletRequestWrapperHttpServletResponseWrapper),用于增强原生HttpServletRequestHttpServletResponse对象的功能。例如,可以使用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框架&#xff0c;以其简洁、高效和易用的特点&#xff0c;赢得了广大开发者的青睐。其内置的多种功能更是为开发者提供了极大的便利&#xff0c;本文将详细介绍Spring Boot中记录请求数据、请求/响应包装器、特殊的过滤器Filter以及Controlle…...

撸猫变梳毛?怎么解决猫咪掉毛问题?好用的宠物空气净化器推荐

秋风一吹&#xff0c;新一轮的猫咪换毛季又到了&#xff0c;这也意味着我失去了撸猫自由。我每天的治愈方式就是下班撸猫&#xff0c;抚摸着柔软的毛发&#xff0c;好像一天的烦恼都消除了。可是一到换毛季&#xff0c;猫还没撸两下&#xff0c;先从猫咪身上带下一手毛&#xf…...

人声分离免费软件,六款好用软件处理音乐更轻松!

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

数据分析Power BI设置万为单位的数据

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

(AI 生成) 新时代游击方式: 利用 “灵活就业“ 红利

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

Unity UndoRedo(撤销重做)功能

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

28条有关人工智能的名言

当谈到人工智能&#xff08;AI&#xff09;的潜力和潜在风险&#xff0c;以及无人类干预的机器学习和推理过程时&#xff0c;目前尚存在许多不同的观点。 只有时间会告诉我们&#xff0c;这些语录中哪一条是最接近未来的真实情况的。在我们尚未到达目的地之前&#xff0c;想一想…...

搞机器视觉项目看不起搞机器视觉培训的,实际上怎么样

搞机器视觉项目第一要务就是验收回款&#xff0c;往往欠款的非常严重&#xff0c;多数还要打通人际关系需要大量的成本。大多数机器视觉检测项目具有一定的风险&#xff0c;客户要求不明确&#xff0c;技术评估不充分&#xff0c;往往伴随着失败的可能性。所以做项目又累又担风…...

使用Jenkins部署项目

部署中的痛点 为什么要用Jenkins&#xff1f;我说下我以前开发的痛点&#xff0c;在一些中小型企业&#xff0c;每次开发一个项目完成后&#xff0c;需要打包部署&#xff0c;可能没有专门的运维人员&#xff0c;只能开发人员去把项目打成一个exe包&#xff0c;可能这个项目已…...

【机器学习与神经网络荣获诺贝尔奖】科学边界的扩展及技术革新

【机器学习与神经网络荣获诺贝尔奖】科学边界的扩展及技术革新 1&#xff09;科学交叉融合的体现2&#xff09;方法论的创新3&#xff09;社会影响的考量 一、机器学习与神经网络的发展前景1&#xff09;生产制造领域2&#xff09;金融领域3&#xff09;医疗领域 二、机器学习和…...

Javascript扩展符号(...)使用说明

在 ES6 中&#xff0c;扩展运算符&#xff08;spread operator&#xff09;... 可以用于在函数调用、数组字面量或对象字面量中展开数组或对象。以下是扩展运算符的一些常见用法&#xff1a; 1. 在函数调用中使用扩展运算符 扩展运算符可以在函数调用时展开数组或对象&#x…...

giugughk

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

【微服务】网关 - Gateway(下)(day8)

网关过滤工厂 在上一篇文章中&#xff0c;主要是对网关进行了一个总体的介绍&#xff0c;然后对网关中的断言进行了一个描述。在这篇文章中&#xff0c;主要是对网关中的最后一大核心——过滤进行介绍。 当客户端发送过来的请求经过断言之后&#xff0c;如果还想在请求前后添…...

【C#】创建一个控制台应用程序来管理学生成绩

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

鸿蒙开发之ArkUI 界面篇 三十四 容器组件Tabs 自定义TabBar

如果需要修改Tabs的图标和文字之间的距离我们该怎么办呢&#xff1f;好在tabBar是联合类型&#xff0c;提供了自定义tabBar&#xff0c;这里就可以显示特殊图标或者是文字图片&#xff0c;如下图&#xff1a; 这里定义了myBuilder的函数&#xff0c;用了 来修饰&#xff0c;没有…...

AI核身-金融场景凭证篡改检测YOLO原理

引言 YOLO (You Only Look Once) 模型是一种先进的实时目标检测算法&#xff0c;它在计算机视觉领域具有重要的地位。YOLO以其速度和准确性而闻名&#xff0c;能够快速识别图像和视频中的各种物体。这使得它在自动驾驶、安全监控、机器人技术、医学影像分析等众多领域都有着广…...

鹅厂JS面试题——0.1+0.2=0.3吗?

首先公布答案:在JavaScript 中&#xff0c;0.1 0.2 ≠ 0.3 为什么&#xff1f; JavaScript 中的数字使用 IEEE 754 标准的双精度浮点数&#xff08;64 位&#xff09;进行表示。这种表示方式在处理十进制小数时&#xff0c;不能精确地表示某些数字。比如0.1 和 0.2 这样的十进…...

软件功能测试重点和流程有哪些?专业软件测评服务公司推荐

软件功能测试就是对产品的各功能进行验证&#xff0c;根据功能测试用例&#xff0c;逐项测试&#xff0c;检查产品是否达到用户要求的功能。功能测试也叫黑盒测试或数据驱动测试&#xff0c;只需考虑需要测试的各个功能&#xff0c;不需要考虑整个软件的内部结构及代码.一般从软…...

【数据结构】AVL树(C++实现)

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

AMD新推EPYC与MI325X,挑战英伟达AI市场地位

在人工智能&#xff08;AI&#xff09;加速器领域&#xff0c;AMD近日于美国旧金山举办的“推进人工智能”&#xff08;Advancing AI Event&#xff09;活动中&#xff0c;宣布了一系列新产品的发布&#xff0c;直接对标英伟达&#xff0c;意图在AI芯片市场占据更大份额。 AMD新…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中&#xff0c;我们会遇到使用 java 调用 dll文件 的情况&#xff0c;此时大概率出现UnsatisfiedLinkError链接错误&#xff0c;原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用&#xff0c;结果 dll 未实现 JNI 协…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力

引言&#xff1a; 在人工智能快速发展的浪潮中&#xff0c;快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型&#xff08;LLM&#xff09;。该模型代表着该领域的重大突破&#xff0c;通过独特方式融合思考与非思考…...

如何在网页里填写 PDF 表格?

有时候&#xff0c;你可能希望用户能在你的网站上填写 PDF 表单。然而&#xff0c;这件事并不简单&#xff0c;因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件&#xff0c;但原生并不支持编辑或填写它们。更糟的是&#xff0c;如果你想收集表单数据&#xff…...

#Uniapp篇:chrome调试unapp适配

chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器&#xff1a;Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...

【Go语言基础【12】】指针:声明、取地址、解引用

文章目录 零、概述&#xff1a;指针 vs. 引用&#xff08;类比其他语言&#xff09;一、指针基础概念二、指针声明与初始化三、指针操作符1. &&#xff1a;取地址&#xff08;拿到内存地址&#xff09;2. *&#xff1a;解引用&#xff08;拿到值&#xff09; 四、空指针&am…...

Web后端基础(基础知识)

BS架构&#xff1a;Browser/Server&#xff0c;浏览器/服务器架构模式。客户端只需要浏览器&#xff0c;应用程序的逻辑和数据都存储在服务端。 优点&#xff1a;维护方便缺点&#xff1a;体验一般 CS架构&#xff1a;Client/Server&#xff0c;客户端/服务器架构模式。需要单独…...

【p2p、分布式,区块链笔记 MESH】Bluetooth蓝牙通信 BLE Mesh协议的拓扑结构 定向转发机制

目录 节点的功能承载层&#xff08;GATT/Adv&#xff09;局限性&#xff1a; 拓扑关系定向转发机制定向转发意义 CG 节点的功能 节点的功能由节点支持的特性和功能决定。所有节点都能够发送和接收网格消息。节点还可以选择支持一个或多个附加功能&#xff0c;如 Configuration …...

windows系统MySQL安装文档

概览&#xff1a;本文讨论了MySQL的安装、使用过程中涉及的解压、配置、初始化、注册服务、启动、修改密码、登录、退出以及卸载等相关内容&#xff0c;为学习者提供全面的操作指导。关键要点包括&#xff1a; 解压 &#xff1a;下载完成后解压压缩包&#xff0c;得到MySQL 8.…...

libfmt: 现代C++的格式化工具库介绍与酷炫功能

libfmt: 现代C的格式化工具库介绍与酷炫功能 libfmt 是一个开源的C格式化库&#xff0c;提供了高效、安全的文本格式化功能&#xff0c;是C20中引入的std::format的基础实现。它比传统的printf和iostream更安全、更灵活、性能更好。 基本介绍 主要特点 类型安全&#xff1a…...

Android写一个捕获全局异常的工具类

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