Spring-Boot

Spring Boot 中的 Max-HTTP-Header-Size

1、概览 Spring Boot Web 应用默认包含一个预配置的嵌入式 Web 服务器。有时候需要对这个服务器进行一些定制来满足特殊的需求。 本文将会带你了解如何在 Spring Boot 应用中通过 max-http-header-size 配置属性来限制客户端的 Header 大小。 2、Max-HTTP-Header-Size Spring Boot 支持将 Tomcat、Undertow 和 Jetty 作为嵌入式服务器。通常,会在 Spring Boot 应用的 application.properties 文件或 application.yaml 文件中定义服务器配置。 大多数 Web 服务器对 HTTP 请求头有自己的大小限制。HTTP 请求头的值受服务器实现的限制。在 Spring Boot 应用中,可以使用 server.max-http-header-size 配置属性来配置最大允许的 HTTP Header 的大小 Tomcat 和 Jetty 的默认值为 8kB,而 Undertow 的默认值为 1MB。 在 application.properties 文件中添加该属性,修改最大 HTTP Header 大小: server.max-http-header-size=20000 同样,application.yaml 格式也是如此: server: max-http-header-size: 20000 从 Spring Boot 2.1 开始,可以使用 DataSize 格式的值:

使用 Spring Boot 和 GraalVM 构建原生镜像

1、概览 本年将带你了解原生镜像(Native Image)的相关知识,以及如何使用 Spring Boot 和 GraalVM 构建原生镜像应用。 本文使用的是 Spring Boot 3,但是在末尾会教你如何解决与 Spring Boot 2 的差异问题。 2、原生镜像 原生(本地)镜像是一种将 Java 代码构建为独立可执行文件的技术。该可执行文件包括应用程序类、其依赖项的类、运行时库类以及来自 JDK 的静态链接本地代码。JVM 被打包到原生镜像中,因此在目标系统上不需要任何 Java 运行环境,但构建产物依赖于平台。因此,需要为每个支持的目标系统进行一次构建,在使用 Docker 等容器技术时会更加简单,将容器构建为一个目标系统,可以部署到任何 Docker 运行时。 2.1、GraalVM 和 Native Image Builder 通用递归应用和算法语言虚拟机(Graal VM)是一个高性能的 JDK 发行版,专为 Java 和其他 JVM 语言编写,同时支持 JavaScript、Ruby、Python 和其他几种语言。它提供了一个原生镜像生成器(Native Image builder),这是一个从 Java 应用中生成原生代码并将其与 VM 一起打包成独立可执行文件的工具。Spring Boot Maven 和 Gradle Plugin 除了少数 例外情况(Mockito 目前不支持原生测试),正式支持该工具。 2.2、两个特性 在构建原生镜像时,会遇到两个典型特性。 Ahead-Of-Time(AOT)编译是将高级 Java 代码编译成本地可执行代码的过程。通常由 JVM 的即时编译器 (JIT) 在运行时进行编译,这样可以在执行应用程序时进行观察和优化。在 AOT 编译的情况下,这一优势就不复存在了。 通常,在进行 AOT(Ahead-of-Time)编译之前,可以选择进行一个单独的步骤,称为 AOT 处理,即从代码中收集元数据并提供给 AOT 编译器。将这两个步骤分开是有意义的,因为 AOT 处理可以是针对特定框架的,而 AOT 编译器更加通用。下面的图片给出了一个概览:

Spring Boot 使用 Log4j2 将日志数据写入 Syslog

1、概览 日志是每个应用的重要组成部分。在应用中,可以将日志存储在文件或数据库中。除此以外,还可以将日志数据发送到集中式日志管理应用,如 Graylog 或 Syslog。 本文将带你了解如何在 Spring Boot 应用中使用 Log4j2 将日志信息发送到 Syslog 服务器。 2、Log4j2 Log4j2 是 Log4j 的最新版本。它是高性能日志记录的常见选择,并被广泛应用于许多生产应用中。 2.1、Maven 依赖 在 pom.xml 中添加 spring-boot-starter-log4j2 依赖。 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j2</artifactId> <version>2.5.2</version> </dependency> 要在 Spring Boot 应用中配置 Log4j2,需要从 pom.xml 中的任何 Starter 中排除默认的 Logback 日志框架。 在本文示例项目中,只有 spring-boot-starter-web Starter 依赖。 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> </dependency> 2.2、Log4j2 配置 现在,创建 Log4j2 配置文件。Spring Boot 会在 classpath 中搜索 log4j2-spring.xml 或 log4j2.xml 文件。 在 resource 目录中配置一个示例 log4j2-spring.

更改 Spring Boot 中 Log4j2 配置文件的默认位置

1、概览 本文将会带你了解如何在 Spring Boot 应用中修改 Log4j2 配置文件的默认位置。 2、通过配置文件更改 默认情况下,把 Log4j2 配置文件(log4j2.xml / log4j2-spring.xml)放在项目的 classpath 或 resources 文件夹中。 可以在 application.properties 中修改该文件的位置: logging.config=/path/to/log4j2.xml 3、通过 VM 参数修改 还可以在运行程序时通过以下 VM 参数来指定 log4j2 的配置文件: -Dlogging.config=/path/to/log4j2.xml 4、编程式配置 最后,还可以通过更改 Spring Boot Application 类,以编程方式配置该文件的位置: @SpringBootApplication public class Application implements CommandLineRunner { public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Override public void run(String... param) { // Log4j2 的 Configurator 类 Configurator.initialize(null, "/path/to/log4j2.xml"); } } 这种解决方案有一个缺点:应用启动过程不会使用 Log4j2 输出日志。

Spring Boot 配置 Kafka SSL 双向认证

1、简介 本文将带你了解在 Spring Boot 中如何配置 SSL 认证以连接到 Apache Kafka Broker。 安全套接字层(SSL)实际上已被弃用,自 2015 年起被传输层安全(TLS)所取代。不过,由于历史原因,Kafka(和 Java)仍然使用 “SSL”。 2、SSL 概览 默认情况下,Apache Kafka 以明文形式发送所有数据,且不进行任何身份认证。 首先,可以为 Broker 和客户端之间的加密配置 SSL。默认情况下,这需要使用公钥加密进行单向身份认证,由客户端验证服务器证书。 此外,服务器还可以使用单独的机制(如 SSL 或 SASL)对客户端进行身份认证,从而实现双向身份认证或相互 TLS(mTLS)。基本上,双向 SSL 认证确保客户端和服务器都使用 SSL 证书来认证对方的身份,并在双向上相互信任。 在本文中,Broker 使用 SSL 对客户端进行身份验证,使用 Keystore 和 Truststore 保存证书和密钥。 每个 Broker 都需要自己的 Keystore,其中包含私钥和公共证书。客户端使用其 Truststore 来验证该证书并信任服务器。同样,每个客户端也需要自己的 Keystore,其中包含私钥和公共证书。服务器使用其 Truststore 来验证和信任客户端的证书,并建立安全连接。 Truststore 可以包含一个可以签署证书的证书颁发机构(CA)。在这种情况下,Broker 或客户端会信任由 Truststore 中的 CA 签发的任何证书。这就简化了证书验证,因为添加新客户端或 Broker 无需更改 Truststore。 3、依赖和设置 创建一个简单的 Spring Boot 示例应用,在 pom.xml 中添加 spring-kafka 依赖: <dependency> <groupId>org.

根据不同的 Profile 激活不同的 Log4j2 配置

1、概览 本文将带你了解如何在 Spring Boot 中根据不同的 Profile 激活不同的 Log4j2 配置。 2、使用不同的配置文件 例如,假设我们有两个文件:log4j2.xml 和 log4j2-dev.xml,一个用于默认配置文件,另一个用于 dev Profile。 创建 application.properties 文件,指定日志配置文件: logging.config=/path/to/log4j2.xml 接着,为 dev Profile 创建一个名为 application-dev.properties 的新 properties 文件,并添加类似的日志配置: logging.config=/path/to/log4j2-dev.xml 如果还有其他的 Profile,例如 prod,只需为其创建一个名称相似的 properties 文件 - application-prod.properties。特定 Profile 的属性总是优先于默认属性。 3、编程式配置 可以通过更改 Spring Boot Application 类,以编程方式选择使用哪个 Log4j2 配置文件: @SpringBootApplication public class Application implements CommandLineRunner { @Autowired private Environment env; public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Override public void run(String... param) { if (Arrays.

在 Spring Boot 应用中使用 Filewatch 监控目录的变化

概览 有时我们需要在应用中监控本地磁盘上的某个目录,在目录中的文件发生变化时(创建、编辑、删除)进行相应的处理。 在 Java 中有好几种方式可以实现监控目录。 Java WatchService API:在 Java 7 中引入,属于低级 API。 Apache commons io:提供了一个用于监控文件系统事件的组件。 Spring Integration 的文件支持:这是 Spring integration 项目的一部分,该项目支持多种企业集成模式。 Spring Boot Developer Tools 中的 Filewatch: 它可以观察本地文件系统的变化。 本文将带你了解如何通过 Spring Boot Developer Tools 中的 Filewatch 来监控系统目录。它本身就是基于 Spring 构建,所以可以和 Spring Boot 无缝集成。 用例 我们希望通过将 csv 文件复制到特定位置(目录)来在应用中创建新的客户。一旦文件完全传输完成,就对其进行读取。然后,对 csv 文件进行验证、处理并移动到目标目录。以下是csv文件的示例: name, email, dob, info, vip James Hart,james.hart@gmail.com,12/05/2002,Information for James,No Will Avery,will.avery@gmail.com,23/10/1991,Information for Will,Yes Anne Williams,anne.williams@gmail.com,12/05/1975,Information for Anne,No Julia Norton,julia.norton@gmail.com,23/10/1984,Information for Julia,Yes csv 文件始终包含标题行和按特定顺序排列的 5 列。

Spring Boot + jOOQ 教程 - 5:多对多关系检索

上一教程 介绍了如何使用 jOOQ 检索一对多关系的记录。本文将带你了解如何使用 jOOQ 检索多对多关系的记录。 你可以通过 Github 获取到完整的源码。 在示例数据库中,有 bookmarks(书签)表和 tags(标签)表。每个书签可以关联多个标签,反之亦然,因此 bookmarks 表和 tags 表之间存在多对多的关系。 让我们看看如何获取书签列表以及与之关联的标签 首先,创建 BookmarkWithTags record。 package com.sivalabs.bookmarks.models; import java.util.List; public record BookmarkWithTags(Long id, String title, String url, List<TagInfo> tags) { public record TagInfo (Long id, String name){} } 使用 MULTISET Value 构造器获取多对多关系 使用 jOOQ 的 MULTISET Value Constructor 来获取书签列表和标签。 实现获取书签和标签,如下: package com.sivalabs.bookmarks.repositories; import com.sivalabs.bookmarks.models.BookmarkWithTags; import org.jooq.DSLContext; import org.springframework.stereotype.Repository; import java.util.List; import static com.sivalabs.bookmarks.jooq.Tables.BOOKMARK_TAG; import static com.

Spring Boot + jOOQ 教程 - 4:一对多关系检索

上一教程 中介绍了如何使用 jOOQ 检索一对一(*One-to-One)关系的记录。本文将带你了解如何使用 jOOQ 检索一对多(One-to-Many)关系的记录。 你可以在 Github 获取完整的源码。 在示例数据库中,有 users(用户)表和 bookmarks(书签)表。每个用户可以创建多个书签,因此 users 表和 bookmarks 表之间是一对多的关系。 让我们看看如何获取用户详细信息以及用户创建的书签。 首先,创建 UserWithBookmarks Record。 package com.sivalabs.bookmarks.models; import java.util.List; public record UserWithBookmarks(Long id, String name, String email, List<BookmarkInfo> bookmarks) { public record BookmarkInfo (Long id, String title, String url){} } 使用 MULTISET Value 构造器获取一对多关系 使用 jOOQ 的 MULTISET Value 构造函数来获取用户创建的书签列表。有关 MULTISET Value 构造函数的更多详情,请访问:https://www.jooq.org/doc/latest/manual/sql-building/column-expressions/multiset-value-constructor/。 此外,强烈推荐你阅读《jOOQ 3.15 的新 Multiset Operator 将如何改变你对 SQL 的看法》一文。 实现获取用户详细信息以及该用户创建的书签。 @Repository public class UserRepository { .

Spring Boot + jOOQ 教程 - 3:一对一关系检索

上一教程 介绍了如何使用 jOOQ 实现基本的 CRUD 操作。本文将带你了解如何使用 jOOQ 检索一对一(One-to-One)关系的记录。 你可以在 Github 上找到完整的源码。 一般来说,在显示记录列表时,只会显示记录的最基本的信息,当点击记录时,才会显示记录的完整信息。 在本示例应用中,用户列表只显示 id、name 和 email 基本信息。当点击详情时,才显示包含用户偏好(Preferences)的完整信息。 更新 findUserById() 方法,以获取用户偏好设置。 首先,创建 UserPreferences record。 public record UserPreferences(Long id, String theme, String language) { } 更新 User 类,使其包含 UserPreferences。 package com.sivalabs.bookmarks.models; public record User ( Long id, String name, String email, String password, UserPreferences preferences ) { public User(Long id, String name, String email, String password) { this(id, name, email, password, null); } public static User create(Long id, String name, String email, String password) { return new User(id, name, email, password, null); } } 在 SQL 中,可以使用 LEFT OUTER JOIN 查询获取关联数据,如下所示: