Spring-Boot

使用 Spring Boot 创建 GraphQL API

GraphQL 是啥? 根据其 官方文档,“GraphQL 是一种用于 API 的查询语言,也是一种服务器端运行时,可使用你为数据定义的类型系统来执行查询”。该语言由 Meta 公司开发并开源,目前由众多公司和个人社区共同维护。 GraphQL 包括 2 个主要部分: Schema Definition Language(Schema 定义语言) - 使用 GraphQL SDL(Schema 定义语言)指定服务的 GraphQL Schema,有时也称为 GraphQL Schema 语言。 Query Language(查询语言) - 查询语言由Query、Mutation 和 Subscription 三部分组成 本文稍后会进行介绍。 GraphQL 有很多出色的功能,例如: 它实现了声明式数据获取,并提供了一个单一的端点,客户端可以准确地指定所需的信息,不再需要过度获取信息。 它提供开箱即用的验证和类型检查功能,你可以在执行前在 GraphQL 强类型系统中验证查询。 GraphQL 可以使 API 文档与 API 的更改保持同步。这对开发人员非常有益,因为他们无需花费太多时间来编写 API 文档。 GraphQL 通过在字段级别废除 API,消除了对版本控制的需求。旧字段可以在不影响现有查询的情况下从 Schema 中删除。 也有一些缺点: GraphQL 需要客户端和服务器端更多的工具支持。这需要大量的前期付出。对于非常简单的 API 用例来说,这不是一个合适的替代方案。 GrpahQL 只有一个入口,默认使用 HTTP POST。这就妨碍了客户端 HTTP 缓存的充分使用,并使得实现缓存成为一项相对复杂的任务。 GraphQL Schema GraphQL 服务必须使用 Schema。GraphQL Schema 定义了如何从服务器请求和返回数据,并由 GraphQL SDL 控制。

在 Spring Boot 中禁用 Keycloak Security

1、概览 Keycloak 是一个开源的身份和访问管理解决方案。在测试阶段,禁用 Keycloak 可能有助于专注于业务测试。而且在测试环境中可能没有 Keycloak 服务器。 本文将带你了解如何禁用 Keycloak starter 的配置,以及如何在项目中启用 Spring Security 后如何对其进行修改。 2、在非 Spring Security 环境下禁用 Keycloak 我们首先来看看如何在不使用 Spring Security 的应用中禁用 Keycloak。 2.1、应用设置 首先,添加 spring-boot-starter-oauth2-client 依赖。 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-oauth2-client</artifactId> </dependency> 此外,还需要添加 spring-boot-starter-oauth2-resource-server 依赖。它将允许我们使用 Keycloak 服务器验证 JWT Token: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-oauth2-resource-server</artifactId> </dependency> 接下来,在 application.properties 中添加 Keycloak 服务器的配置: spring.security.oauth2.client.registration.keycloak.client-id=login-app spring.security.oauth2.client.registration.keycloak.authorization-grant-type=authorization_code spring.security.oauth2.client.registration.keycloak.scope=openid spring.security.oauth2.client.provider.keycloak.issuer-uri= http://localhost:8080/realms/SpringBootKeycloak spring.security.oauth2.client.provider.keycloak.user-name-attribute=preferred_username spring.security.oauth2.resourceserver.jwt.issuer-uri=http://localhost:8080/realms/SpringBootKeycloak 最后,添加 UserController 来检索用户: @RestController @RequestMapping("/users") public class UserController { @GetMapping("/{userId}") public User getCustomer(@PathVariable Long userId) { return new User(userId, "John", "Doe"); } } 2.

在 Spring Boot 中使用 Spring Security + JWT + MySQL 实现基于 Token 的身份认证

本文将会带你了解在 Spring Boot 中如何使用 Spring Security、JWT 和 MySQL 数据库实现基于 Token 的身份认证。 JWT (JSON Web Token)概览 JWT 是 JSON Web Token 的缩写,是一种安全地在各方之间传输信息的开放标准。它是一种紧凑、自包含的数据传输方法,通常用于客户端和服务器之间的数据传输。 JWT 通常用于认证和授权,服务器通过验证 JWT 中包含的数字签名来验证用户。 JWT 由三部分组成:Header、Payload 和 Signature(签名)。 Header 包含 Token 类型和 Token 签名算法的元数据。 Payload 包含关于被验证用户或实体的声明(Claim)或陈述。这些声明可包括用户 ID、用户名或电子邮件地址等信息。 Signature(签名)使用秘钥和 Header 及 Payload 生成,以确保 JWT 的完整性。 使用 JWT 的一个好处是它们是无状态的,这意味着服务器无需跟踪用户的身份认证状态。这可以提高可扩展性和性能。此外,JWT 可以在不同的域和服务中使用,只要它们共享相同的秘钥来验证签名即可。 Spring Security 概览 Spring Security 是一个提供身份认证、授权和防护常见攻击的框架。它为确保 Web 和响应式应用程序的安全提供一流的支持,是保护基于 Spring 的应用程序的事实标准。 Spring Security 用于保护 Web 应用程序、REST API 和微服务的安全,为身份认证和授权提供内置支持。 数据库表结构 添加 Maven 依赖 添加如下依赖到 Spring Boot 项目:

在 Spring Boot 中校验用户上传的图片文件

图片上传是现代应用中非常常见的一种功能,也是风险比较高的一个地方。恶意用户可能会上传一些病毒、木马。这些东西不仅严重威胁服务器的安全还浪费了带宽,磁盘等资源。所以,在图片上传的接口中,一定要对用户上传的文件进行严格的校验。 本文介绍了 2 种对图片文件进行验证的方法可供你参考。 文件后缀校验 通过文件后缀(也就是文件扩展名,通常用于表示文件的类型),进行文件类型校验这是最常见的做法。 图片文件的后缀类型有很多,常见的只有:jpg、jpeg、gif、png、webp。我们可以在配置或者代码中定义一个“允许上传的图片后缀”集合,用于校验用户上传的图片文件。 package cn.springdoc.demo.web.controller; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Set; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; @RestController @RequestMapping("/upload") public class UploadController { // 允许上传的图片类型的后缀集合 static final Set<String> imageSuffix = Set.of("jpg", "jpeg", "gif", "png", "webp"); @PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE) public ResponseEntity<String> upload (@RequestParam("file") MultipartFile file ) throws IllegalStateException, IOException{ // 文件的原始名称 String fileName = file.getOriginalFilename(); if (fileName == null) { return ResponseEntity.

使用 Testcontainers 测试 Redis

1、概览 Testcontainers 是一个用于创建临时 Docker 容器进行单元测试的 Java 库。当我们想要避免使用实际服务器进行测试时,它非常有用。 本文将会带你了解如何在 Spring Boot 中使用 Testcontainers 测试 Redis。 2、项目设置 使用任何测试容器的首要前提是在运行测试的机器上安装 Docker。 安装好 Docker 后,就可以开始设置 Spring Boot 应用了。 在此应用中,我们将设置一个 Redis Hash、一个 Repository 和一个使用 Repository 与 Redis 交互的 Service。 2.1、依赖 添加所需的 spring-boot-starter-test 和 spring-boot-starter-data-redis 依赖。 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> 接着,还要添加 Testcontainers 依赖: <dependency> <groupId>org.testcontainers</groupId> <artifactId>testcontainers</artifactId> <version>1.17.2</version> <scope>test</scope> </dependency> 2.2、配置 在 application.properties 文件中添加 Redis 连接的详细信息: spring.redis.host=127.0.0.1 spring.redis.port=6379 3、应用设置 我们要创建一个小型应用,向 Redis 数据库读写 Product(产品)。 3.1、Entity 创建 Product 类。

使用 Testcontainers 对 Keycloak 进行集成测试

1、简介 通常我们会通过集成测试来验证应用功能是否正常。集成测试至关重要,特别是对于认证这种敏感且重要的功能。Testcontainers 允许在测试阶段启动 Docker 容器,以便对实际的技术栈运行测试。 本文将带你了解如何使用 Testcontainers 针对实际的 Keycloak 实例设置集成测试。 2、配置 Spring Security 和 Keycloak 我们需要配置 Spring Security、Keycloak 和 Testcontainers。 2.1、整合 Spring Boot 和 Spring Security 在 pom.xml 中添加 spring-boot-starter-security 依赖。 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> 接着,创建一个示例 Controller,它返回一个 User。 @RestController @RequestMapping("/users") public class UserController { @GetMapping("me") public UserDto getMe() { return new UserDto(1L, "janedoe", "Doe", "Jane", "jane.doe@baeldung.com"); } } 至此,我们有了一个受保护的 Controller,用于处理对 /users/me 端点的请求。启动应用时,Spring Security 会为用户 user 生成一个密码,该密码在控制台输出的日志中。 2.配置 Keycloak 启动本地 Keycloak 的最简单方法是使用 Docker。

Spring Boot 中的静态资源配置

Spring Boot 对静态资源提供了支持。默认情况下,以下目录为默认的静态资源目录。其中的静态资源可以被直接访问: classpath:/META-INF/resources/ classpath:/resources/ classpath:/static/ classpath:/public/ ${user.dir}/public/ (程序运行目录下的 public 目录) 优先级从上往下,当多个静态资源目录中出现同名文件时,越靠上的目录权重越高。 静态资源的处理类是 ResourceHttpRequestHandler,它会正确地处理资源的 Last-Modified 响应和 Range 请求。 静态资源和 RequestMapping 冲突 如果静态资源路径和 @RequestMapping 路径冲突,则 @RequestMapping 优先。 例如,有如下 Controller: @RestController @RequestMapping public class DemoController { @GetMapping("/foo") public ResponseEntity<String> foo () { // 返回字符串 “controller” return ResponseEntity.ok("controller"); } } 在 src/main/resources/public 目录下有一个名为 foo 的文本文件,内容如下: public 启动应用,访问 http://localhost:8080/foo: $ curl http://localhost:8080/foo controller 你可以看到,响应的内容是 controller,说明 controller 的 @RequestMapping 优先。 另外,对于这种没有后缀、未知类型的静态资源,Spring Boot 会以 “下载” 的形式响应给客户端(添加了 Content-Disposition 响应头)。

在 Spring Boot 中实现定时备份 MySQL 数据库

应用系统中最重要的东西就是 “数据”,定期备份数据的重要性就不言而喻了。本文将会带你了解如何在 Spring Boot 应用中实现定期备份 MySQL 数据库。 mysqldump MYSQL本身提供了一个工具 mysqldump,通过它可以完成数据库的备份。 简单来说就是一个命令,可以把数据库中的表结构和数据,以 SQL 语句的形式输出到标准输出: mysqldump -u[用户名] -p[密码] [数据库] > [备份的SQL文件] 注意,命令中的 > 符号在linux下是重定向符,在这里的意思就是把标准输出重定向到文件。 例如,备份 demo 库到 ~/mysql.sql,用户名和密码都是 root: mysqldump -uroot -proot demo > ~/mysql.sql mysqldump 的详细文档:https://dev.mysql.com/doc/refman/en/mysqldump.html 创建应用 创建任意 Spring Boot 应用,并添加 commons-exec 依赖。 <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-exec --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-exec</artifactId> <version>1.3</version> </dependency> 由于我们的备份是通过新启动一个子进程调用 mysqldump 来完成,所以建议使用 apache 的 commons-exec 库。它的使用比较简单,且设计合理,包含了子进程超时控制,异步执行等等功能。 应用配置 spring: # 基本的数据源配置 datasource: type: com.zaxxer.hikari.HikariDataSource driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://127.0.0.1:3306/demo?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2b8&allowMultiQueries=true username: root password: root app: # 备份配置 backup: # 备份数据库 db: "demo" # 备份文件存储目录 dir: "backups" # 备份文件最多保留时间。如,5分钟:5m、12小时:12h、1天:1d max-age: 3m 如上,我们配置了基本的数据源。以及自定义的 “备份配置”,其中指定了备份文件的存储目录,要备份的数据库以及备份文件滚动存储的最大保存时间。

在 Spring Boot 中校验 Boolean 类型

1、简介 在本文中,我们将学习如何在 Spring Boot 中的不同层(如 controller 或 service)上验证布尔(Boolean)类型以及执行验证的各种方式。 2、编程式验证 Boolean 类提供了两个创建该类实例的基本方法:Boolean.valueOf() 和 Boolean.parseBoolean()。 Boolean.valueOf() 可接受 String 和 boolean 值。它会检查输入参数的值是 true 还是 false,并相应地提供一个 Boolean 对象。Boolean.parseBoolean() 方法只接受 String 值。 这些方法不区分大小写,例如,true、True、TRUE、false 和 FALSE 都是可以的。 通过单元测试来验证 String 到 Boolean 的转换: @Test void givenInputAsString_whenStringToBoolean_thenValidBooleanConversion() { assertEquals(Boolean.TRUE, Boolean.valueOf("TRUE")); assertEquals(Boolean.FALSE, Boolean.valueOf("false")); assertEquals(Boolean.TRUE, Boolean.parseBoolean("True")); } 验证从基本 boolean 值到 Boolean 封装类的转换: @Test void givenInputAsboolean_whenbooleanToBoolean_thenValidBooleanConversion() { assertEquals(Boolean.TRUE, Boolean.valueOf(true)); assertEquals(Boolean.FALSE, Boolean.valueOf(false)); } 3、使用自定义 Jackson Deserializer 进行验证 Spring Boot API 经常需要处理 JSON 数据,我们还要了解如何通过数据反序列化验证 JSON 到 Boolean 值的转换。我们可以使用自定义 deserializer 反序列化 boolean 值的自定义表示。

使用 Spring Boot 构建 GraphQL API

GraphQL 是一种用于 API 的查询语言和运行时,它允许 API 消费者精确获取所需的信息,而不是服务器完全控制响应内容。某些 REST API 实现需要从多个 URL 加载资源的引用,而 GraphQL API 可以在单个响应中跟踪相关对象之间的引用并返回它们。 本教程逐步演示了如何使用 Spring Boot 和 Spring for GraphQL 构建一个 GraphQL API,用于查询 Neo4j 数据库中相关公司、人员和属性的示例数据集。它还演示了如何使用 Next.js 和 MUI Datagrid 构建一个 React 客户端来消费该 API。客户端和服务器都使用 Auth0 进行认证、授权,服务器使用 Okta Spring Boot Starter,客户端使用 Auth0 React SDK。 如果你想跳过所有步骤,直接运行程序,那么你可以以按照 GitHub Repository 中的 README 说明进行操作。 本文所使用的工具、服务如下: Node.js v18.16.1 npm 9.5.1 Java OpenJDK 17 Docker 24.0.2 Auth0 account Auth0 CLI 1.0.0 HTTPie 3.2.2 Next.js 13.4.19 使用 Spring for GraphQL 构建 GraphQL API 资源服务器(Resource Server)是一个 Spring Boot Web 应用,使用 Spring for GraphQL 暴露了一个 GraphQL API。该 API 允许使用 Spring Data Neo4j 查询 Neo4j 数据库,其中包含公司及其相关所有者和属性的信息。数据来自 Neo4j 用例示例。