教程

设置 Swagger 文档中的示例和描述

1、概览 在本教程中,我们将演示如何使用 Swagger 注解使我们的文档更具描述性。我们会学习如何为 API 的不同部分(如方法、参数、响应等)添加描述,以及如何添加请求/响应示例。 2、项目设置 我们将创建一个简单的 Product API,提供创建和获取 product 的方法。 要从头开始创建 REST API,我们可以按照 Spring 文档中的教程 使用 Spring Boot 创建 RESTful Web 服务。 下一步是为项目设置依赖和配置。我们可以按照 本文 中的步骤使用 Spring REST API 设置 Swagger 2 3、创建 API 创建 Product API 并检查生成的文档。 3.1、Model 定义 Product 类: public class Product implements Serializable { private long id; private String name; private String price; // 省略 get/set 构造函数 } 3.2、Controller 定义两个 API 方法: @RestController @Tag(name = "Products API") public class ProductController { @PostMapping("/products") public ResponseEntity<Void> createProduct(@RequestBody Product product) { //creation logic return new ResponseEntity<>(HttpStatus.

Spring REST Docs 与 OpenAPI 的比较

1、概览 Spring REST Docs 和 OpenAPI 3.0 是为 REST API 创建 API 文档的两种方法。 在本教程中,我们将探讨它们的相对优缺点。 2、前世今生 Spring REST Docs 是由 Spring 社区开发的一个框架,用于 为RESTful API 创建准确的文档。它采用了测试驱动的方法,文档可用 Spring MVC tests、Spring Webflux 的 WebTestClient 或 REST-Assured 形式编写。 运行测试的结果会生成 AsciiDoc 文件,可以使用 Asciidoctor 将它们组合在一起,生成描述 API 的 HTML 页面。由于它遵循 TDD 方法,Spring REST Docs 自动带来了许多优势,例如减少代码错误、减少重复工作和更快的反馈周期等。 而,OpenAPI 是一种诞生于 Swagger 2.0 的规范。截至本文撰写时,其最新版本为 3.0,并有许多已知的 实现。 与其他规范一样,OpenAPI 也为其实现制定了一些基本规则。简而言之,所有 OpenAPI 实现都应该以 JSON 或 YAML 格式的 JSON 对象生成文档。 还有 许多工具 可以接收 JSON/YAML,并输出 UI 界面来可视化和导航 API。这在验收测试时非常有用。在这里的代码示例中,我们将使用 Springdoc - 一个用于 OpenAPI 3 和 Spring Boot 的框架。

在 Spring 应用中整合 Apache Kafka 以生产、消费消息

1、概览 Apache Kafka 是一个分布式且容错的流处理系统。 在本教程中,我们将介绍 Spring 对 Kafka 的支持以及它在原生 Kafka Java 客户端 API 之上提供的抽象层。 Spring Kafka 通过 KafkaTemplate 和使用 @KafkaListener 注解的消息驱动的POJO,提供了简单且典型的 Spring template 编程模型。 2、安装和设置 要下载和安装 Kafka,请参阅 此处 的官方指南。 我们需要在 pom.xml 中添加 spring-kafka 依赖: <dependency> <groupId>org.springframework.kafka</groupId> <artifactId>spring-kafka</artifactId> <version>3.0.0</version> </dependency> 然后按如下方法配置 spring-boot-maven-plugin: <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <mainClass>com.baeldung.spring.kafka.KafkaApplication</mainClass> </configuration> </plugin> 我们的示例应用程序是 Spring Boot。 本文假定服务器使用默认配置启动,并且没有更改服务端口。 3、配置 Topic 之前,我们使用命令行工具在 Kafka 中创建主题: $ bin/kafka-topics.sh --create \ --zookeeper localhost:2181 \ --replication-factor 1 --partitions 1 \ --topic mytopic 但随着 Kafka 引入 AdminClient,我们现在可以以编程式创建 topic。

在 AWS Lambda 中运行 Spring Boot 应用

1、概览 在本教程中,我们将探讨如何使用 Serverless Application Model (SAM) 框架将 Spring Boot 应用程序部署到 AWS Lambda。 这种方法有助于将现有的 API 服务器迁移到 serverless 上。 通过这种方法,我们可以利用 AWS Lambda 的可扩展性和按执行付费的定价模式,高效、经济地运行我们的应用程序。 2、理解 Lamdba AWS Lambda 是亚马逊网络服务(AWS)提供的 serverless 计算服务。它允许我们在无需配置或管理服务器的情况下运行代码。 Lambda 函数与传统服务器的主要区别之一是,Lambda 函数由事件驱动,生命周期很短。 Lambda 函数不像服务器那样持续运行,而是只在响应特定事件时才运行,例如 API 请求、队列中的消息或上传到 S3 的文件。 我们应该注意到,lambda 在处理第一个请求时需要一定的时间来启动。这就是所谓的 “冷启动”。 如果下一个请求在短时间内出现,可以使用相同的 lambda 运行时,这被称为 “热启动”。如果同时出现多个请求,则会启动多个 Lambda 运行时。 与 Lambda 理想的毫秒级启动时间相比,Spring Boot 的启动时间相对较长,因此我们会讨论这对性能的影响。 3、项目设置 我们通过修改 pom.xml 和添加一些配置来迁移现有的 Spring Boot 项目。 Spring Boot 支持的版本有 2.2.x、2.3.x、2.4.x、2.5.x、2.6.x 和 2.7.x。 3.1、Spring Boot API 示例 我们的应用程序由一个简单的 API 组成,它可以处理对 api/v1/users 端点的任何 GET 请求:

Spring Boot 3 中匹配以斜线结尾的 URL

1、概览 在本教程中,我们将学习 Spring Boot 3(Spring 6)在 URL 匹配方面引入的变化。 Spring Boot 使用 DispatcherServlet 处理 URL 映射,它会根据 URL 将请求转发到相应的 controller。DispatcherServlet 使用一组称为映射(mapping)的规则来确定使用哪个 controller 来处理请求。 2、Spring MVC 和 Webflux URL 匹配的更改 Spring Boot 3 对“尾斜线匹配”配置选项进行了重大修改。该选项决定是否将带尾斜线的 URL 与不带尾斜线的 URL 作相同处理。以前版本的 Spring Boot 默认将此选项设置为 true。这意味着 controller 默认会同时匹配 GET /some/greeting 和 GET /some/greeting/: @RestController public class GreetingsController { @GetMapping("/some/greeting") public String greeting { return "Hello"; } } 如上,如果我们尝试访问带有尾斜线的 URL,就会收到 404 错误。 让我们来探讨一下如何适应这种变化。 3、添加额外的路由 要处理这种问题,可以额外添加一个专门处理带尾斜线的路由: @RestController public class GreetingsController { @GetMapping("/some/greeting") public String greeting { return "Hello"; } @GetMapping("/some/greeting/") public String greeting { return "Hello"; } } 下面是一个使用 Webflux 的响应式 @RestController:

在 Spring Boot 应用中使用 Resilience4j

1、概览 Resilience4j 是一个轻量级的容错库,提供了诸如熔断、重试、限流、超时、隔板等功能,可以帮助应用程序在面对故障和不稳定条件时保持可用性和可靠性。 在本教程中,我们将学习如何在 Spring Boot 应用程序中使用 Resilience4j。 2、项目设置 2.1、Maven 依赖 首先,我们需要添加 spring-boot-starter-web starter 来创建一个简单的 web 应用: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> 接下来,我们需要 resilience4j-spring-boot2 和 spring-boot-starter-aop 依赖,以便在 Spring Boot 中通过注解使用 Resilience-4j 库的功能: <dependency> <groupId>io.github.resilience4j</groupId> <artifactId>resilience4j-spring-boot2</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> 此外,我们还需要添加 spring-boot-starter-actuator 依赖,以便通过暴露一组端点来监控应用的当前状态: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> 最后,还要添加 wiremock-jre8 依赖,用于帮助我们使用 mock HTTP server 测试 REST API: <dependency> <groupId>com.github.tomakehurst</groupId> <artifactId>wiremock-jre8</artifactId> <scope>test</scope> </dependency> 2.2、RestController 和外部 API 调用 在使用 Resilience4j 库的不同功能时,我们的 web 应用需要与外部 API 进行交互。因此,我们需要添加一个 RestTemplate bean,用于 API 调用:

在 Spring Boot 中加载多个 YAML 配置文件

1、概览 在设计 Spring Boot 应用程序时,我们通常希望使用外部配置来定义 application properties。这样,我们就可以在不同的环境中使用相同的代码。在某些情况下,即使是同一个环境,我们可能希望将属性定义在多个 YAML 配置文件中。 在本教程中,我们将学习在 Spring Boot 应用中加载多个 YAML 配置文件的两种方法。 2、使用 Spring Profiles 在应用程序中包含多个 YAML 配置文件的一种方法是使用 Spring profiles。 这种方法利用了 “Spring 自动加载与 profiles 相关联的 YAML 配置文件” 的功能。 接下来,让我们以两个 .yml 文件为例进行说明。 2.1、YAML 配置 我们的第一个文件列出了 student 列表。我们将其命名为 application-students.yml,并将其放在 ./src/main/resources 目录中: students: - Jane - Michael 我们将第二个文件命名为 application-teachers.yml,并放置在相同的 ./src/main/resources 目录中: teachers: - Margo - Javier 2.2. Application 现在,让我们来设置我们的示例应用。我们将在应用中使用 CommandLineRunner 来查看属性加载情况: @SpringBootApplication public class MultipleYamlApplication implements CommandLineRunner { @Autowired private MultipleYamlConfiguration config; public static void main(String[] args) { SpringApplication springApp = new SpringApplication(MultipleYamlApplication.

在 Spring Cache 中获取 Caffeine 缓存的所有 KEY

1、概览 在本文中,我们将学习如何在使用 Spring Cache 时获取 Caffeine 缓存中的所有缓存 KEY。 2、Spring Cache 缓存(Cache)是 Spring Framework 不可分割的一部分。从 3.1 版本开始,它就是 Spring 生态系统的一部分。因此,它拥有一套定义明确、久经考验的接口。 让我们来看看其中两个主要接口: CacheManager 和 Cache: interface CacheManager { Cache getCache(String name); Collection<String> getCacheNames(); } public interface Cache { String getName(); Object getNativeCache(); ValueWrapper get(Object key); <T> T get(Object key, @Nullable Class<T> type); <T> T get(Object key, Callable<T> valueLoader); void put(Object key, @Nullable Object value); ValueWrapper putIfAbsent(Object key, @Nullable Object value); void evict(Object key); void clear(); } 我们可以看到,CacheManager 是应用程序中可用缓存的注册中心。而 Cache 对象则是缓存内的一组键值对。

JUnit 5 根据激活的 Profile 进行测试

1、概览 我们经常需要为开发和部署过程中的不同阶段创建不同的配置。在 Spring Boot 应用中,我们可以为每个不同的阶段定义一个 Spring Profile 并为其创建专门的测试。 在本教程中,我们将介绍如何使用 JUnit 5 基于激活的 Spring Profile 来进行测试。 2、项目设置 首先,在我们的项目中添加 spring-boot-starter-web 依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> 现在,让我们创建一个简单的 Spring Boot 应用: @SpringBootApplication public class ActiveProfileApplication { public static void main (String [] args){ SpringApplication.run(Application.class); } } 最后,创建 application.yaml 配置文件。 3、Spring Profile Spring Profile 提供了一种方法,通过对每个环境的特定配置进行分组,来定义和管理不同的环境。 通过激活特定的 Profile,我们可以在不同的配置之间轻松切换。 3.1、在 Properties 中激活 Profile 我们可以在 application.yaml 文件中指定要激活的 profile: spring: profiles: active: dev 现在 Spring 将检索激活的 profile 的所有属性,并将所有专用 Bean 加载到 application context 中。

在 Spring Boot 应用中同时上传文件、JSON和表单数据

一般我们会使用 multipart/form-data 请求来上传文件。multipart/form-data 请求可以有多个子请求体,每个子请求体都可以有自己的 header 和 body。 本文将带你了解如何在 Spring Boot 应用中使用 multipart/form-data 请求同时上传文件、JSON、表单数据。 服务端 Controller 定义文件上传 controller。 package cn.springdoc.demo.controller; import java.io.IOException; import java.io.InputStream; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.MediaType; import org.springframework.util.StreamUtils; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import cn.springdoc.demo.model.Meta; @RestController @RequestMapping("/upload") public class UploadController { private static final Logger log = LoggerFactory.getLogger(UploadController.class); /** * 文件上传 * @param file * @param response * @return * @throws IOException */ @PostMapping(consumes = MediaType.