教程

Spring Boot REST API 最佳实践 - 第三章

在本章节教程中,我们将了解如何实现 FindById 和 DeleteById API 端点。 Spring Boot REST API 最佳实践 - 第一章:实现 Get Collection API Spring Boot REST API 最佳实践 - 第二章:实现 Create 和 Update API Spring Boot REST API 最佳实践 - 第三章:实现 FindById 和 DeleteById API(本文) Spring Boot REST API 最佳实践 - 第四章:REST API 的异常处理 你可以在此 GitHub 仓库中找到本教程的示例代码。 实现 GET /api/bookmarks/{id} API 端点 我们希望实现一个根据指定 id 获取单个资源的 API 端点,如果找到,以 HTTP 状态码 200 返回。如果未找到,则返回 HTTP 状态码 404,可选择返回包含异常信息的响应体。 实现 GET /api/bookmarks/{id} API 端点,如下:

Spring Boot REST API 最佳实践 - 第二章

在本章节教程中,我将介绍我们在实现创建和更新 API 端点时应遵循的一些最佳实践。 Spring Boot REST API 最佳实践 - 第一章:实现 Get Collection API Spring Boot REST API 最佳实践 - 第二章:实现 Create 和 Update API(本文) Spring Boot REST API 最佳实践 - 第三章:实现 FindById 和 DeleteById API Spring Boot REST API 最佳实践 - 第四章:REST API 的异常处理 本文是 Spring Boot REST API 最佳实践 - 第一章 的续章。因此,如果你还没有阅读,请先阅读第一章。我们将在第一章中实现的代码基础上构建 API。 你可以在此 GitHub 仓库中找到本教程中的示例代码。 实现 POST /api/bookmarks API 端点 我们可以考虑按如下方式实现 POST /api/bookmarks API 端点: package com.sivalabs.bookmarks.api.controllers; import com.

Spring Boot REST API 最佳实践 - 第一章

在本章节教程中,我将介绍我们在实现 REST API 时应遵循的一些最佳实践,和开发人员常犯的一些错误以及如何避免这些错误。 Spring Boot REST API 最佳实践 - 第一章:实现 Get Collection API(本文) Spring Boot REST API 最佳实践 - 第二章:实现 Create 和 Update API Spring Boot REST API 最佳实践 - 第三章:实现 FindById 和 DeleteById API Spring Boot REST API 最佳实践 - 第四章:REST API 的异常处理 在第一章中,我们将实现第一个 API 端点,即获取资源列表。我们将了解开发人员常犯的一些错误以及如何避免这些错误。 创建 Spring Boot 应用 首先,访问 https://start.springboot.io,选择 Spring Web、Validation、Spring Data JPA、PostgreSQL Driver、Flyway Migration 和 Testcontainers starter,创建一个 Spring Boot 应用程序。 我们的示例应用及其简单,但却是按真实应用程序中遵循的相同实践进行操作。 本教程中的示例代码,可以在 GitHub 中找到。

在 Spring Boot 中监听 Redis Key 过期事件

在 Redis 数据库中,可以通过 EXPIRE、EXPIREAT、EXPIRETIME 命令来设置 Key 的有效时间,当一个 Key 过期后会自动从数据库中删除,释放空间。 得益于于这个特性,我们可以很轻松地实现诸多类似于 “Session” 管理、数据缓存等功能。它们都有一个共同点就是,数据不会永久保存! 在有些场景中,我们可能希望在某些 Key 过期的时候获取到通知,进行一些业务处理。或者是干脆用于 “定时通知/任务” 功能,例如:下单 30 分钟后未支付,则取消订单。那么可以在用户下单的时候使用订单号作为 key 设置到 Redis 数据库中,并且设置过期时间为 30 分钟。当超时后,我们可以在 “key 过期通知” 中获取到 key 也就是订单号,判断用户是否已经支付从而是否取消订单。 注意: Redis 的 Key 过期通知功能本质上是通过 发布/订阅 功能实现的。也就是说,它不能保证通知消息的交付,当 Key 过期时如果服务器停机、重启中则该通知消息会永久丢失。 本文将会带你学习如何在 Spring Boot 应用中使用 Spring Data Redis 监听 Redis Key 过期事件。 本文所使用的软件版本: Spring Boot:3.1.3 Redis:7.0.5 整合 Spring Data Redis 得益于 Spring Boot 对 Redis 开箱即用的支持,只需要 2 步,就可以快速地在 Spring Boot 中整合、使用 Redis。

单例设计模式与 Spring Boot 中的 Singleton Bean

1、概览 单例对象经常被开发人员使用,因为应用程序中的许多对象都需要重复使用一个单例。在 Spring 中,我们可以通过 使用 Spring 的单例 Bean 或自己实现单例设计模式 来创建单例对象。 在本教程中,我们将首先了解单例设计模式及其线程安全的实现。然后,我们将了解 Spring 中的 Singleton Bean Scope,并将 singleton Bean 与使用单例设计模式创建的对象进行比较。 最后,我们将介绍一些可行的最佳实践。 本文中的 “Singleton Bean”,即“单例 bean”。 2、单例设计模式 单例是 “GoF” (si人帮?)于 1994 年发布的最简单的设计模式之一。它被归类于创建模式,因为单例提供了一种只创建一个实例的方法。 2.1、模式定义 单例模式是指由一个类负责创建对象,并确保只创建一个实例。我们经常使用单例来共享状态或减少创建多个对象的成本。 单例模式实现可以确保只创建一个实例: 通过实现单个私有构造函数来隐藏所有构造函数。 仅在实例不存在时创建实例,并将其存储在私有静态变量中。 使用公共静态 getter 方法访问该单例。 让我们看看几个使用单例对象的类的示例: 在上面的类图中,我们可以看到多个服务如何使用只创建一次的同一个单例。 2.2、懒加载 单例模式实现通常使用懒加载来延迟实例创建(也称为“懒汉式”),直到第一次实际需要时才创建。为了确保延迟实例化,我们可以在首次调用静态 getter 方法时创建实例: public final class ThreadSafeSingleInstance { private static volatile ThreadSafeSingleInstance instance = null; private ThreadSafeSingleInstance() {} public static ThreadSafeSingleInstance getInstance() { if (instance == null) { synchronized(ThreadSafeSingleInstance.class) { if (instance == null) { instance = new ThreadSafeSingleInstance(); } } } return instance; } // 标准的 getter 方法 } 在多线程应用中,延迟加载可能会导致并发问题。因此,我们还应用了双重检查锁,以防止不同线程创建多个实例。

RestTemplate 中 exchange()、postForEntity() 和 execute() 之间的区别

1、简介 在本教程中,我们将了解 RestTemplate 类中 exchange()、postForEntity() 和 execute() 方法之间的区别。 2、RestTemplate 是啥? RestTemplate 是 Spring 框架 中的一个工具类,它能让发送 HTTP 消息和处理响应变得简单。RestTemplate 类提供了许多功能,非常适合编写简单的 HTTP 客户端: 支持所有标准 HTTP 方法(GET、POST 等)。 能够处理所有标准 MIME Type(JSON、XML、表单等)。 高级 API 允许我们使用 Java 代码进行配置,并避免复杂的序列化问题。 可使用 ClientHttpRequestInitializer 和 ClientHttpRequestInterceptor 接口进行自定义。 2.1、废弃警告 从 Spring 5 开始,RestTemplate 类逐渐被弃用。虽然它在 Spring 6 中仍然存在,但维护者已经明确表示,该类今后不会再有任何改进,只接受较小的错误和安全修复。 因此,我们鼓励开发人员使用 WebClient。该类拥有更现代的 API,支持同步、异步和 stream 场景。 3、RestTemplate 基本用法 RestTemplate 通过提供具有相应名称的 public 方法,让使用标准 HTTP 方法变得简单。 例如,要发送 GET 请求,我们可以使用带有 getFor 前缀的多种重载方法之一。其他 HTTP 方法也类似,包括 POST、PUT、DELETE、HEAD 和 PATCH。 所有这些方法的结构几乎相同。它们基本上只需要有关的 URL 信息,以及请求和响应体的表示方法。header 等信息会自动生成。

从 Spring Boot 2 升级到 Spring Boot 3

1、概览 在本教程中,我们将学习如何将 Spring Boot 应用迁移到 3.0 版本。当前所使用的 Spring Boot 版本是 2.7,并且 Java 版本是 17。 2、核心的变化 Spring Boot 3.0 是该框架的一个重要里程碑,对其核心组件进行了多项重要修改。 2.1、配置属性 部分属性的修改: spring.redis 已移至 spring.data.redis。 spring.data.cassandra 已移至 spring.cassandra。 移除了spring.jpa.hibernate.use-new-id-generator。 server.max.http.header.size 已移至 server.max-http-request-header-size。 移除了对 spring.security.saml2.relyingparty.registration.{id}.identity-provider 的支持。 要识别这些属性,我们可以在 pom.xml 中添加 spring-boot-properties-migrator: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-properties-migrator</artifactId> <scope>runtime</scope> </dependency> 最新版本的 spring-boot-properties-migrator 可从 Maven Central 获取。 该依赖会在启动时生成并打印一份报告,列出已废弃的属性名称,并在运行时临时迁移这些属性。 2.2、Jakarta EE 10 新版 Jakarta EE 10 对 Spring Boot 3 的相关依赖进行了更新: Servlet 规范更新至 6.0。 JPA 规范更新至 3.1。 因此,如果我们未通过 spring-boot-starter 来自动管理这些依赖的版本,我们就应该手动更新它们。

在 Spring Boot 中使用 Flyway 进行数据库迁移

在之前的 Spring Boot JdbcTemplate 教程 中,我们见识了如何使用 schema.sql 和 data.sql 脚本初始化数据库。这对于演示项目可能有用,但对于实际应用,我们应该使用数据库迁移工具。 Flyway 是最流行的基于 Java 的数据库迁移工具。可以将 Flyway 作为独立库,或使用 flyway-maven-plugin 或使用 Flyway Gradle 插件进行数据库迁移。 Spring Boot 提供了开箱即用的支持,用于 Flyway 数据库迁移。让我们看看如何创建一个使用 Spring Data JPA 与 PostgreSQL 数据库交互,并使用 Flyway 实现数据库迁移的 Spring Boot 应用。 首先,访问 https://start.springboot.io/,选择 Spring Web、Spring Data JPA、PostgreSQL Driver、Flyway Migration 和 Testcontainers starter,创建 Spring Boot 应用程序。 创建 Flyway 迁移脚本 Flyway 遵循 V<VERSION>__<DESCRIPTION>.sql 命名约定来命名其版本化的迁移脚本。让我们在 src/main/resources/db/migration 文件夹下添加以下两个迁移脚本。 V1__create_tables.sql: create table bookmarks ( id bigserial not null, title varchar not null, url varchar not null, created_at timestamp, primary key (id) ); V2__create_bookmarks_indexes.

将 Spring Boot 应用构建为 War 包

Spring Boot 最具特色的功能就是使用嵌入式服务器,可以把应用构建为一个独立、可执行的 jar,这极大地方便了部署。但是仍有人希望把应用打包为 WAR 包,部署在外部的 Servlet 容器(Tomcat、Jetty 等)中运行。 本文将会指导你如何更改 Spring Boot 的打包方式为 War,并且部署到外部服务器中(Servlet 3.x +)。 Spring Boot 打包为 War 包的步骤 1、修改打包方式 <packaging>war</packaging> 修改 packaging 节点值为 war。Maven 工程默认打包方式为 jar,如果你的 pom.xml 中没有 packaging 节点,则需要手动设置。 2、修改 Servlet 容器的 scope <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency> 由于我们会使用外部的 Tomcat,所以需要主动把嵌入式容器 spring-boot-starter-tomcat 依赖的 scope 声明为 provided,表示该依赖只用于编译、测试。 3、修改启动类,继承 SpringBootServletInitializer package cn.springdoc.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; @SpringBootApplication public class DemoApplication extends SpringBootServletInitializer{ public static void main(String[] args) { SpringApplication.

使用 Spring Data Redis 配置 Redis TTL

1、简介 在本教程中,我们将学习如何在 Spring Data Redis 中配置 key 的过期时间。 2、项目设置 假设我们有一个整合了 spring data redis 的 spring boot 项目,我们打算使用 redis 来管理用户的会话(Session)。 2.1、依赖 首先,在 pom.xml 中添加以下依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <version>3.0.4</version> </dependency> spring-boot-starter-data-redis 将传递依赖 spring-data-redis 和 lettuce-core。 2.2、Redis 配置 其次,添加 RedisTemplate 配置: @Configuration public class RedisConfiguration { @Bean public RedisTemplate<String, Session> getRedisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplate<String, Session> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(redisConnectionFactory); return redisTemplate; } } 2.3、Model 第三,创建 Session model: @RedisHash public class Session { @Id private String id; private Long expirationInSeconds; } 2.