当前位置: 首页 > 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新…...

电脑桌面文件不见了怎么恢复?8个方法帮你解决问题

电脑桌面文件突然不见了凭空消失了怎么恢复&#xff1f;电脑桌面文件日常使用电脑时&#xff0c;很多用户喜欢将重要文件、快捷方式存放在桌面上&#xff0c;以方便快速访问。然而&#xff0c;有时我们会突然发现桌面上的文件不见了。桌面文件消失可能有多种原因&#xff0c;例…...

如果想转行AI领域却不知如何开始?可以试试这五步,超详细_ai行业怎么入行

我看了计算机科学家大卫格维茨写的一篇博客&#xff0c;里面介绍了如果想从事AI行业&#xff0c;却不知道如何开始的话&#xff0c;可以走下面五步&#xff0c;从而达到转行的目的。因为这是个国外作家写的&#xff0c;跟我们国内的情况有一些出入&#xff0c;但是大思路是没有…...

个人博客搭建 | Hexo框架

文章目录 1.Hexo安装2.创建博客3.将博客通过GitHub来部署4.更换主题 1.Hexo安装 Hexo 是一个快速、简洁且高效的博客框架。Hexo 使用 Markdown&#xff08;或其他标记语言&#xff09;解析文章&#xff0c;在几秒内&#xff0c;即可利用靓丽的主题生成静态网页。搭建Hexo首先要…...

[Gtk] layout.ui

播放器layout&#xff1a; # <?xml version"1.0" encoding"UTF-8"?> <!-- Generated with glade 3.38.2 --> <interface> <requires lib"gtk" version"3.20"/> <object class"GtkWindow"…...

Spring MVC:精通JSON数据返回的几种高效方式

前言 在实际开发中&#xff0c;我们在前后端传送数据通常使用Json格式&#xff0c;而在Spring MVC中返回Json格式的方式有多种&#xff0c;接下来我将介绍其中一些。 准备工作 为了演示Json格式的数据&#xff0c;我们准备一个实体类&#xff0c;例如User&#xff0c;这些可以测…...

[LeetCode 题3] 没有重复字符的最长的子字符串

问题描述 输入&#xff1a;一个字符串 s。输出&#xff1a;最长的无重复字符的子串的长度。 示例 输入: s "abcabcbb" 输出: 3 解释: 最长的无重复字符的子串是 "abc"&#xff0c;长度为 3。 输入: s "bbbbb" 输出: 1 解释: 最长的无重复字…...

YoloDotNet 在工业检测中的应用详解

文章目录 一、数据收集与标注二、模型选择与训练三、检测流程设计四、结果评估与优化五、与工业生产线集成一、数据收集与标注 在工业检测中,首先需要收集大量的相关工业产品图像数据。这些数据应涵盖不同的产品类型、缺陷种类以及各种可能的生产状态。例如,对于电子产品的检…...

DataFrame增删改数据

目录 准备数据 DataFrame添加列 直接添加列数据 使用insert添加列数据 DataFrame删除行列 准备数据 删除行 删除列 DataFrame数据去重 准备数据 import pandas as pd df pd.read_csv("../data/b_LJdata.csv") df DataFrame添加列 直接添加列数据 1&…...

一站式解决App下载量统计,Xinstall引领新潮流

在移动应用市场中&#xff0c;App下载量是衡量应用受欢迎程度和市场表现的重要指标。然而&#xff0c;对于许多开发者而言&#xff0c;如何精准统计App下载量却是一个不小的挑战。幸运的是&#xff0c;如今有了一款专业的App全渠道统计服务商——Xinstall&#xff0c;它能够帮助…...

ijkMediaPlayer+ TextureView 等比全屏播放视频(避免拉伸)

TextureView默认以fitxy的方式加载surface数据&#xff0c;如果需要等比全屏播放视频&#xff0c;避免拉伸&#xff0c;可以采用Matrix对TextureView进行变换 废话不多说&#xff0c;直接上代码 public class BaseIjkPlayer implements TextureView.SurfaceTextureListener{/…...