Spring-Boot

Spring Boot 定时推送 Websocket 消息

1、概览 本文将带你了解如何在 Spring Boot 中实现定时地往浏览器推送 WebSockets 消息。 另一种方法是使用服务器发送事件 (SSE),但本文不涉及这一点。 Spring 提供了多种调度方式。如 @Scheduled 注解,以及 Project Reactor 提供的 Flux::interval 方法,对于 Webflux 应用来说,该方法开箱即用,它还可以作为独立库用于任何 Java 项目。 此外,还有一些更专业的三方调度框架,如 Quartz Scheduler,但这不在本文范畴。 2、简单的聊天应用 在 上一篇文章 中,使用 WebSockets 构建了一个聊天应用。现在让我们用一项新功能来扩展它:聊天机器人。聊天机器人是向浏览器推送预定消息的服务器端组件。 2.1、Maven 依赖 先在 Maven 中添加必要依赖, pom.xml 如下: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> <dependency> <groupId>io.projectreactor</groupId> <artifactId>reactor-core</artifactId> </dependency> <dependency> <groupId>com.github.javafaker</groupId> <artifactId>javafaker</artifactId> <version>1.0.2</version> </dependency> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> </dependency> 2.2、JavaFaker 使用 JavaFaker 库生成机器人信息。该库通常用于生成测试数据。在这里,用于为聊天室添加一位名为 “Chuck Norris” 的访客。 代码如下: Faker faker = new Faker(); ChuckNorris chuckNorris = faker.

Spring Boot 自定义 Jackson ObjectMapper

1、概览 Spring Boot 默认使用 Jackson ObjectMapper 实例来序列化和反序列化 JSON 格式的响应与请求。 本文将带你了解如何在 Spring Boot 中自定义 Jackson ObjectMapper 选项,以及配置序列化和反序列化选项的最常用方法。 2、默认配置 默认情况下,Spring Boot 禁用了以下功能: MapperFeature.DEFAULT_VIEW_INCLUSION DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES SerializationFeature.WRITE_DATES_AS_TIMESTAMPS 从一个简单的例子开始: 客户端向 /coffee?name=Lavazza 端点发送 GET 请求。 Controller 返回一个新的 Coffee 对象。 Spring 使用 ObjectMapper 将 POJO 序列化为 JSON。 使用 String 和 LocalDateTime 对象来演示自定义选项: public class Coffee { private String name; private String brand; private LocalDateTime date; // get / set 省略 } 定义一个简单的 REST Controller 来演示序列化: @GetMapping("/coffee") public Coffee getCoffee( @RequestParam(required = false) String brand, @RequestParam(required = false) String name) { return new Coffee() .

Spring-boot:repackage 和 Maven package

1、概览 Apache Maven 是一种广泛使用的项目依赖管理工具和项目构建工具。 Spring Boot 通过 Spring Boot Maven Plugin 在 Apache Maven 中提供了对 Spring Boot 的支持。 众所周知,在 Maven 中可以使用 mvn package 将应用打包为 JAR 或 WAR 包。不过,Spring Boot Maven 插件额外添加了一个 repackage goal,也可以在 mvn 命令中调用。 有时,这两个 mvn 命令会让人混淆。本文将带你了解 mvn package 和 spring-boot:repackage 之间的区别。 2、Spring Boot 应用示例 首先,创建一个简单的 Spring Boot 应用作为示例: @SpringBootApplication public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } } 创建一个简单的 REST 端点来验证应用是否正常运行: @RestController public class DemoRestController { @GetMapping(value = "/welcome") public ResponseEntity welcomeEndpoint() { return ResponseEntity.

Spring Boot 3.2 中开箱即用的虚拟线程和 GraalVM

Spring Boot 3.2 前几天 发布 了,让我们用 Java 21、GraalVM 和 Virtual Threads(虚拟线程)来快速体验一下。 Spring Boot 3.2 支持: Java 21 虚拟线程 原生镜像(自 2022 年 11 月 Spring Boot 3.0 发布以来,Spring Boot 已在生产中支持 GraalVM 原生镜像) Java 21 2023 年 9 月 19 日 Java 21 发布。 正如宣布的那样,Java 21 在性能、稳定性和安全性方面进行了数千项改进,包括平台增强功能,这有助于开发人员提高生产力,推动整个组织的创新和发展。 Project Loom 其中一个比较重要的更新是虚拟线程(Virtual Thread),这是 Project Loom 提供的功能。具体细节这里就不多说了,你可以参考官方的 JEP:https://openjdk.org/jeps/444。 GraalVM 和 Native image GraalVM 是一款高性能 JDK,可使用另一种即时(JIT)编译器提高 Java 和基于 JVM 的应用程序的性能。 原生镜像(Native image)是一种将 Java 代码提前编译成独立可执行文件(称为原生镜像)的技术。该可执行文件包括应用程序类、其依赖项中的类、运行时库类以及 JDK 中静态链接的本地代码。

使用 RestClient 上传文件、JSON 和表单数据

前几天 Spring Boot 3.2 正式 发布 了,本次发布带来了一个新的 HTTP 客户端:RestClient,它提供了 Fluent 风格的 API,比起 RestTemplate 来说更加优雅。 关于 RestClient 的更多信息,你可以参考如下文章: Spring RestClient 教程 Spring 6.1的新特性:RestClient 本文将会带你了解如何使用 RestClient 同时上传文件、JSON 和表单数据。 关于如何使用 RestTemplate 进行文件上传,你可以参考 “RestTemplate 上传文件” 和 “在 Spring Boot 应用中同时上传文件、JSON和表单数据”。 本文使用的 Spring Boot 版本为 3.2.0。 创建 Controller 首先在 Spring Boot 应用中,创建一个处理 multipart/form-data 文件上传请求的 Controller。 package cn.springdoc.demo.web.controller; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; import org.

Spring Boot 3.2.0 发布

该版本增加了大量新功能和改进。有关完整的 升级说明 以及 新的和值得注意 的功能,请参阅 发布说明。 3.2 中的新特性 3.2 版的亮点包括: 支持虚拟线程(Virtual Threads) 初步支持 JVM Checkpoint Restore(Project CRaC) SSL Bundle 重新加载 大量可观测性的改进 支持 RestClient 支持 JdbcClient 支持 Jetty 12 为 Apache Pulsar 提供 Spring 支持 为 Kafka 和 RabbitMQ 提供 SSL Bundle 支持 重新处理了嵌套 Jar 文件的处理方式 改进 Docker Image 构建 依赖升级 Spring Boot 3.2 迁移到了多个 Spring 项目的新版本,还尽可能升级到了其他第三方库的最新稳定版本。详情请参见 发布说明。 其他变化 发行说明 中还记录了许多其他更改和改进。还可以找到计划在未来删除的废弃类和方法列表。 Ref:https://spring.io/blog/2023/11/23/spring-boot-3-2-0-available-now

Spring Boot Actuator 中的端点管理

1、概览 本文将带你了解如何通过 properties 文件控制 Spring Boot Actuator 端点的状态,以及如何保证端点的安全。 2、设置 为了使用 Actuator,需要在 Maven 配置中包含 spring-boot-starter-actuator: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> <version>3.1.2</version> </dependency> 此外,从 Spring Boot 2.0 开始,如果想通过 HTTP 暴露端点,就需要包含 Web Starter: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>3.1.2</version> </dependency> 3、启用和暴露端点 默认情况下,除 /shutdown 之外的所有端点都已启用,只有 /health 和 /info 被暴露。即使为应用配置了不同的 Root Context,也能在 /actuator 中找到所有端点。 这意味着,一旦在 Maven 配置中添加了相应的 Stater,就可以访问 http://localhost:8080/actuator/health 和 http://localhost:8080/actuator/info 上的 /health 和 /info 端点。 访问 http://localhost:8080/actuator,查看可用端点列表,因为 Actuator 端点已启用 HATEOS。所以,应该能看到 /health 和 /info。 {"_links":{"self":{"href":"http://localhost:8080/actuator","templated":false}, "health":{"href":"http://localhost:8080/actuator/health","templated":false}, "info":{"href":"http://localhost:8080/actuator/info","templated":false}}} 3.1、暴露所有端点 现在,修改 application.

Spring Boot 和 JSP(Java Server Pages)

1、概览 在构建 Java Web 应用时,可以使用 Java Server Pages(JSP)作为 HTML 页面模板。 Spring Boot 是一个流行的框架,可以用它来快速开发 Java Web 应用。 但是,在 Spring Boot 中使用 JSP 有一定的局限性,应该考虑用 Thymeleaf 或 FreeMarker 来替代 JSP。 2、Maven 依赖 首先来看看在 Spring Boot 中使用 JSP 需要哪些依赖。 2.1、作为独立应用运行 首先,添加 spring-boot-starter-web 依赖。 该依赖提供了使用 Spring Boot 和默认的嵌入式 Tomcat Servlet 容器来运行 Web 应用的所有核心依赖。 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.4.4</version> </dependency> 注意,使用 Undertow 作为嵌入式 Servlet 容器使用时不支持 JSP。 接下来,需要添加 tomcat-embed-jasper 依赖,以便应用能够编译和渲染 JSP 页面: <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-jasper</artifactId> <version>9.0.44</version> </dependency> 虽然可以手动提供上述两个依赖,但通常最好让 Spring Boot 管理这些依赖的版本,而我们只需管理 Spring Boot 版本即可。

Spring Boot 将 JSON 中的 Long 值序列化为 String 避免精度丢失

什么是精度丢失? Java 中长整形 Long (64位)的取值范围是:-9223372036854775808 - 9223372036854775807。 在这种情况下,由于 JavaScript 的 Number 类型是 64 位浮点数,它无法精确表示超过 53 位的整数。因此,当将 Java Long 类型的值传递给 JavaScript 时,可能会发生精度丢失。 你可以在浏览器控制台运行如下代码,更直观地感受 “精度丢失” 的问题。 let val = 9223372036854775807; console.log(val); //9223372036854776000 输出的值丢失了精度 如果我们在业务中使用 Long 作为数据类型,那么就必须要考虑浏览器客户端中 Js 存在精度丢失的问题。解决这个问题最简单的办法就是 把 Java 的 Long 值,序列化为字符串传递。 Jackson 的注解支持 Spring Boot 默认使用 Jackson 作为 JSON 的序列化、反序列化框架。Jackson 提供了 @JsonSerialize 注解,该注解的 using 属性可以指定一个 JsonSerializer 的实现类,用于自定义字段的序列化方式。 Jackson 已经预定义了一个实现 ToStringSerializer,用于把指定的字段序列化为字符串。 定义一个简单的 User 对象: package cn.springdoc.demo.model; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; public class User { // 把 Long 类型的 id 序列化为 字符串 @JsonSerialize(using = ToStringSerializer.

Spring Boot 配置 TLS

1、概览 安全通信在现代应用中发挥着重要作用。客户端和服务器之间通过普通 HTTP 进行的通信并不安全。对于生产级的应用,应该在应用中通过 TLS(传输层安全)协议启用 HTTPS。 本文将带你了解如何在 Spring Boot 应用中启用 TLS。 2、TLS 协议 TLS 为客户端和服务器之间的数据传输提供保护,是 HTTPS 协议的关键组成部分。安全套接字层(SSL)和 TLS 经常被互换使用,但两者并不相同。事实上,TLS 是 SSL 的继承者。TLS 可以单向或双向实现。 2.1、单向 TLS 在单向 TLS 中,只有客户端对服务器进行验证,以确保从受信任的服务器接收数据。为实现单向 TLS,服务器会与客户端共享其公共证书。 2.2、双向 TLS 在双向 TLS 或相互 TLS(mTLS)中,客户端和服务器都要相互验证,以确保通信双方都是可信的。在实现 mTLS 时,双方要共享各自的公开证书。 3、Spring Boot 配置 TLS 3.1、生成密钥对 要启用 TLS,需要创建一对公钥/私钥。为此,可以使用 keytool 命令行工具,它默认 随 Java 发行版一起提供。 使用 keytool 生成一对密钥,并将其存储到 keystore.p12 文件中: keytool -genkeypair -alias baeldung -keyalg RSA -keysize 4096 \ -validity 3650 -dname "CN=localhost" -keypass changeit -keystore keystore.