1、概览 Keycloak 是由 Red Hat 管理和在 Java 中由 JBoss 开发的开源身份和访问管理解决方案。
本文将带你了解如何在 在 Spring Boot 中嵌入 Keycloak 服务器,这样就能轻松启动预配置的 Keycloak 服务器。
Keycloak 也可以作为 独立服务器 运行,但需要下载并通过管理控制台进行设置。
2、Keycloak 预配置 服务器包含一组 Realm,每个 Realm 都是用户管理的独立单元。要对其进行预配置,我们需要指定一个 JSON 格式的 Realm 定义文件。
使用 Keycloak Admin 控制台 配置的所有内容都以 JSON 格式进行持久化。
我们的授权服务器将使用名为 baeldung-realm.json 的 JSON 文件进行预配置。文件中的几个相关配置如下:
users:默认用户是 john@test.com 和 mike@other.com;对应的凭证也在这里。 clients:定义一个 ID 为 newClient 的客户端 standardFlowEnabled:设置为 true,激活 newClient 的授权码(Authorization Code)授权模式。 redirectUris:newClient 在成功验证后将重定向到的服务器 URL webOrigins:置为 +,为所有 redirectUris 的 URL 提供 CORS 支持 Keycloak 服务器会默认签发 JWT Token,因此无需为此进行单独配置。接下来看看 Maven 的配置。
1、概览 本文将带你了解 Spring 中 @ConditionalOnProperty 注解的作用和用法。
2、@ConditionalOnProperty 的作用 通常,在开发基于 Spring 的应用时,需要根据配置属性是否存在,或者配置属性有指定的值来有条件地创建一些 Bean。
例如,我们需要注册一个 DataSource Bean,并且要根据属性值设置为 prod 还是 test 来创建生产数据库或测试数据库。
这正是 @ConditionalOnProperty 注解的用武之地。
简而言之,@ConditionalOnProperty 只有在环境属性存在且具有指定值的情况下才会启用 Bean 注册。默认情况下,指定的属性必须已定义且等于指定的值。
熟悉了 @ConditionalOnProperty 注解的用途后,接着来深入了解一下如何使用。
3、@ConditionalOnProperty 注解实践 开发一个基本的电子邮件通知系统来示范 @ConditionalOnProperty 的使用。
首先,创建一个简单的服务来发送通知消息。
定义 NotificationSender 接口:
public interface NotificationSender { String send(String message); } 接下来,提供一个 NotificationSender 接口的实现来发送电子邮件:
public class EmailNotification implements NotificationSender { @Override public String send(String message) { return "Email Notification: " + message; } } 现在,来看看如何使用 @ConditionalOnProperty 注解。
1、概览 当代应用通常需要连接到各种外部服务,如 PostgreSQL、Apache Kafka、Cassandra、Redis 和其他外部 API。
本文将带你了解 Spring 如何通过引入动态属性(@DynamicPropertySource)来帮助测试此类应用。
2、问题:动态属性 假设我们正在开发一个使用 PostgreSQL 作为数据库的应用。
创建 JPA 实体:
@Entity @Table(name = "articles") public class Article { @Id @GeneratedValue(strategy = IDENTITY) private Long id; private String title; private String content; // get、set 省略 } 我们需要编写测试来确保应用按预期运行,由于该测试需要与真实数据库创建连接,我们应该事先建立一个 PostgreSQL 实例。
在测试执行过程中,有不同的方法来设置此类基础工具。事实上,这类解决方案主要有三类:
专门为测试设置一个单独的数据库服务器 使用一些轻量级的、测试专用的替代品,如 H2 让测试本身管理数据库的生命周期 由于未区分测试环境和生产环境,与使用 H2 等测试替身相比,有更好的选择。第三个选项不仅可以与真实数据库一起使用,还可以为测试提供更好的隔离性。此外,借助 Docker 和 Testcontainers 等技术,实现第三个选项非常容易。
如果使用 Testcontainers 等技术,测试流程如下:
在所有测试前设置 PostgreSQL 等组件。通常,这些组件会监听随机端口。 运行测试。 卸载组件。 如果 PostgreSQL 容器每次都监听随机端口,那么我们就应该以某种方式动态设置和更改 spring.datasource.url 配置属性。基本上,每个测试都应该有自己的配置属性版本。
当配置是静态的时候,可以使用 Spring Boot 的配置管理工具轻松地对其进行管理。但是,当我们面对的是动态配置时,同样的任务就会变得比较麻烦。
1、概览 在 Spring Boot 中使用 Swagger 文档时,有时候需要隐藏端点。最常见的情况就是,该端点还在开发中。或者是有一些内部端点,不想暴露给用户。
本文将带你了解如何在 Swagger API 文档中隐藏端点。
2、使用 @ApiIgnore 隐藏端点 可以在 Handler 方法上添加 @ApiIgnore 注解来隐藏端点:
@ApiIgnore @ApiOperation(value = "This method is used to get the author name.") @GetMapping("/getAuthor") public String getAuthor() { return "Umang Budhwar"; } 3、使用 @ApiOperation 隐藏端点 也可以使用 @ApiOperation 来隐藏端点:
@ApiOperation(value = "This method is used to get the current date.", hidden = true) @GetMapping("/getDate") public LocalDate getDate() { return LocalDate.now(); } 将 @ApiOperation 注解的 hidden 属性设置为 true,即可使 Swagger 忽略该端点。
1、Spring 事件机制 有的人可能会觉得 Spring 中的事件机制很神奇,一个地方发消息,另一个地方收消息,跟 MQ 一样。其实,Spring 中的事件本质上就是观察者模式的应用。事件有其便利的一面,但是用多了也容易导致混乱,所以在实际项目中,我们还是要谨慎选择是否使用 Spring 事件。
2、简单实践 先用一个简单的案例,来让大家了解一下 Spring 中事件的应用。
事件发布流程中,有三个核心概念,它们之间的关系如下图:
事件源(ApplicationEvent):这个就是你要发布的事件对象。 事件发布器(ApplicationEventPublisher):这是事件的发布工具。 事件监听器(ApplicationListener):这个相当于是事件的消费者。 以上三个要素,事件源和事件监听器都可以有多个,事件发布器(通常是由容器来扮演)一般来说只有一个。
接下来,让我们通过一个简单的案例来演示一下 Spring 中事件的用法。
首先,我们需要自定义一个事件对象,自定义的事件继承自 ApplicationEvent 类,如下:
public class MyEvent extends ApplicationEvent { private String name; public MyEvent(Object source, String name) { super(source); this.name = name; } @Override public String toString() { return "MyEvent{" + "name='" + name + '\'' + "} " + super.toString(); } } 这里只额外定义了一个 name 属性,如果大家在事件发送的时候需要传递的数据比较多,那么就可以在这里定义更多的属性。
在具体实践中,事件源并非一定要继承自 ApplicationEvent,事件源也可以是一个普通的 Java 类,如果是普通的 Java 类,系统会自动将之封装为一个 PayloadApplicationEvent 对象去发送。
1、概览 Keycloak 是第三方授权服务器,负责管理我们 Web 或移动应用的用户。
它提供了一些默认属性,例如名字、姓氏和电子邮件,用于存储任何给定用户的信息。但是很多时候,这些属性是不够的,我们可能需要添加一些特定于我们应用的额外用户属性。
本文将带你了解如何在 Keycloak 授权服务器中添加自定义用户属性,并在基于 Spring 的后端中访问它们。
2、独立服务器 2.1、添加自定义用户属性 基于上文 “Spring Boot 整合 Keycloak” 中的 Keycloak 服务器。
第一步是进入 Keycloak 的管理控制台。
在 Keycloak 发行版的 bin 文件夹中运行如下命令来启动服务器:
kc.bat start-dev 然后,进入 Web 管理控制台 http://localhost:8180/auth/admin,输入凭证:initial1 / zaq1!QAZ 。
接下来,点击 “Manage” 选项卡下的 “Users”:
在这里,可以看到 之前(上一篇文章)添加的用户:user1。
点击 “ID”,然后转到 “Attributes” 选项卡,添加一个新的属性,即表示出生日期的 “DOB”:
点击 “Save” 后,自定义属性就会添加到用户信息中。
接下来,将此属性作为自定义 Claim 添加到映射中,以便它在用户 Token 的 JSON Payload 中可用。
为此,需要进入管理控制台的 “应用客户端”。回想一下 之前 创建的客户端 login-app:
点击它,然后选择 “Client scopes” 选项卡。在 “Client scopes” 页面点击 “login-app-dedicated” 链接,进入 “Mappers” 选项卡。点击 “Configure a new mapper”,选择 “User Attribute” 创建新 mapper:
1、概览 本文将带你了解如何设置 Keycloak 服务器,以及如何使用 Spring Security OAuth2.0 将 Spring Boot 应用连接到 Keycloak 服务器。
2、Keycloak 是什么? Keycloak 是针对现代应用和服务的开源身份和访问管理解决方案。
Keycloak 提供了诸如单点登录(SSO)、身份代理和社交登录、用户联盟、客户端适配器、管理控制台和账户管理等功能。
本文使用 Keycloak 的管理控制台,使用 Spring Security OAuth2.0 设置和连接 Spring Boot。
3、设置 Keycloak 服务器 设置和配置 Keycloak 服务器。
3.1、下载和安装 Keycloak 有多种发行版可供选择,本文使 Keycloak-22.0.3 独立服务器发行版。点击 这里 从官方下载。
下载完后,解压缩并从终端启动 Keycloak:
unzip keycloak-22.0.3.zip cd keycloak-22.0.3 bin/kc.sh start-dev 运行这些命令后,Keycloak 会启动服务。如果你看到一行类似于 Keycloak 22.0.3 [...] started 的内容,就表示服务器启动成功。
打开浏览器,访问 http://localhost:8080,会被重定向到 http://localhost:8080/auth 以创建管理员进行登录:
创建一个名为 initial1 的初始管理员用户,密码为 zaq1!QAZ。点击 “Create”后,可以看到 “User Created” 的提示信息。
现在进入管理控制台。在登录页面,输入 initial 管理员用户凭证:
1、简介 本文将带你了解如何在 OpenAPI 文件中声明日期(Date)。特别是在使用 Swagger 实现的情况下,这将使我们能够在调用外部 API 时以标准化的方式管理输入和输出日期。
2、Swagger 和 OAS Swagger 是一组工具,实现了 OpenAPI Specification(OAS),它是一种与编程语言无关的接口,用于文档化 RESTful API。这使我们能够了解任何服务的功能,而无需访问源代码。
要实现这一点,需要在项目中创建一个文件,通常是 YAML 或 JSON,使用 OAS 描述 API。然后,使用 Swagger 工具:
通过浏览器(Swagger 编辑器)编辑规范 自动生成 API 客户库(Swagger Codegen) 显示自动生成的文档(Swagger UI) OpenAPI 文件示例 中包含了不同的部分的示例,本文重点关注模型定义。
3、定义日期(Date) 使用 OAS 定义一个 User 实体:
components: User: type: "object" properties: id: type: integer format: int64 createdAt: type: string format: date description: Creation date example: "2021-01-30" username: type: string 定义日期:
type 等于 string format 字段,指定格式为日期(Date) 在本例中,使用 format: date 来描述 createdAt。这使用 ISO 8601 格式的日期。
QueryDSL 是一个用于构建类型安全查询的开源 Java ORM 框架。它提供了一种 Fluent 风格的 API 来构建和执行数据库查询,并提供了编译时类型检查,以避免常见的查询错误。QueryDSL 支持多种数据库,包括关系型数据库和 NoSQL 数据库,可以与多个持久化框架(如 JPA、Hibernate 等)整合使用。它简化了查询的编写过程,使得查询代码更易于理解、维护和重用。
QueryDSL 在 Spring Boot 中通常配合 Spring Data JPA 使用,它会根据定义的 JPA Entity 类自动生成对应的查询类。通过查询类,除了可以快速地进行基本的 CRUD 操作外还支持 JOIN、GROUP、子查询等复杂的检索。而这一切都无需编写任何 SQL 语句,代码即 SQL。
本文将会带你了解如何在 Spring Boot 中整合 QueryDSL + Spring Data JPA,以及 QueryDSL 的常见用法。
示例项目 本文使用到的软件版本:
Java:21 Spring Boot:3.2.0 MySQL:8.0.26 添加依赖 创建 Spring Boot 应用,完整的 pom.xml 如下:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.2.0</version> <relativePath /> <!
1、概览 本文将带你了解 Spring 中 @Valid 和 @Validated 注解的用法和它们之间的区别。
在大多数应用中,验证用户输入是常见的功能。在 Java 生态系统中,一般使用 Java Standard Bean Validation API 来支持这一点,从 Spring 4.0 版本开始,它就与 Spring 完美集成。@Valid 和 @Validated 注解就源自于这个 Standard Bean API。
2、@Valid 和 @Validated 注解 在 Spring 中,通常使用 JSR-303 的 @Valid 注解进行方法级验证,以及用于标记成员属性以进行验证。不过,该注解不支持分组验证。
分组(Group)可以帮助限制在验证过程中应用的约束条件。一个特定的使用案例是 UI 引导(UI wizards)。在第一步中,可能会有一组特定的字段。在后续步骤中,可能还有同一个 Bean 的另一组字段。因此,需要在每个步骤中对这些有限的字段应用约束条件,但是 @Valid 无法支持这样的功能。
对于分组级(Group-Level)验证,必须使用 Spring 的 @Validated,它是 JSR-303 的 @Valid 的变体,用于方法级。对于成员属性的标记,继续使用 @Valid 注解就行。
3、示例 使用 Spring Boot 开发一个简单的用户注册表单。
首先,只有 name 和 password 属性:
public class UserAccount { @NotNull @Size(min = 4, max = 15) private String password; @NotBlank private String name; // 构造函数、Get、Set 省略 } 接下来是 Controller。在 saveBasicInfo 方法参数上使用 @Valid 注解来验证用户输入: