1、简介 DispatcherServlet 在 Spring 应用中扮演着重要角色,它为应用提供了一个入口点。Context Path 定义了终端用户访问应用的 URL。
本文将带你了解 Spring 中 Context Path(上下文路径)与 Servlet Path(Servlet 路径)的区别。
2、Context Path 简而言之,Context Path 是访问 Web 应用时使用的名称。它是应用的根路径。默认情况下,Spring Boot 在 ROOT 上下文路径("/")上提供服务。
因此,默认情况下,Spring Boot 应用可以通过 http://localhost:8080/ 访问。
不过,在某些情况下,我们可能需要更改应用的 Context。配置 Context Path 有多种方法,最简单的方式就是通过位于 src/main/resources 文件夹下的 application.properties 进行配置。
server.servlet.context-path=/demo 如上,此时应用的主页为:
http://localhost:8080/demo 特别是在把应用部署到外部服务器时,往往需要修改应用的 Context Path,以便于其他一起部署的应用分开来。
3、Servlet Path Servlet Path 表示 DispatcherServlet 的 Path。DispatcherServlet 是一个实际的 Servlet,继承自 HttpSerlvet 。默认值与 Context Path 类似,即(“/”):
spring.mvc.servlet.path=/ 在 Boot 的早期版本中,该属性位于 ServerProperties 类中,名称为 server.servlet-path=/。
从 2.
1、简介 在 Apache Kafka 中传输消息时,客户端和服务器会就使用共同的语法格式达成协议。Apache Kafka 提供了默认的转换器(Converter),如 String 和 Long。同时也支持针对特定用例的自定义序列化器 (Serializer)。
2、Apache Kafka 中的 Serializer 序列化是将对象转换为字节的过程。反序列化则是将字节流转换为对象的逆过程。简而言之,它将内容转换为可读和可解释的信息。
如上所述,Apache Kafka 为几种基本类型提供了默认序列化器,并允许我们实现自定义序列化器:
上图显示了通过网络向 Kafka Topic 发送消息的过程。在此过程中,生产者将消息发送到 Topic 之前,自定义序列化器会将对象转换成字节。同样,它也显示了反序列化器如何将字节转换回对象,以便消费者正确处理。
2.1、自定义 Serializer Apache Kafka 为几种基本类型提供了预置的序列化器和反序列化器:
StringSerializer ShortSerializer IntegerSerializer LongSerializer DoubleSerializer BytesSerializer 它也提供了实现自定义序列化器/反序列化器的功能。为了序列化自己的对象,需要实现 Serializer 接口。同样,要创建自定义的反序列化器,需要实现 Deserializer 接口。
这两个接口都有可覆写的方法:
configure:用于实现配置细节 serialize / deserialize:这些方法包括自定义序列化和反序列化的实际实现 close:使用该方法关闭 Kafka Session 3、实现自定义 Serializer Kafka 提供了自定义序列化器的功能。可以为消息的 Key 和 Value 实现特定的转换器(Converter)。
3.1、依赖 在 pom.xml 中添加 Kafka Consumer API 依赖:
<dependency> <groupId>org.apache.kafka</groupId> <artifactId>kafka-clients</artifactId> <version>3.4.0</version> </dependency> 3.
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.
1、概览 本文将会带你了解如何使用 spring-websockets 创建一个 Websocket 应用,并且使用 Postman 来进行测试。
2、Java WebSocket WebSocket 是 Web 浏览器和服务器之间的一种双向、全双工、持久连接。一旦建立了 WebSocket 连接,该连接就会一直打开,直到客户端或服务器决定关闭该连接。
WebSocket 协议是实现应用处理实时消息的一种方式之一。最常见的替代方案是长轮询(long polling)和服务器推送事件(server-sent events)。每种解决方案都有其优点和缺点。
在 Spring 中使用 WebSockets 的一种方式是使用 STOMP 子协议。不过,本文使用原始 WebSockets,因为到目前为止,Postman 还不支持 STOMP。
3、Postman Postman 是一个用于构建和使用 API 的 API 平台。使用 Postman 时,无需为了测试而编写 HTTP 客户端基础设施代码。相反,可以创建称为集合(collections)的测试套件,并让 Postman 与 API 进行交互。
4、WebSocket 应用 创建一个简单的应用,工作流程如下:
服务器向客户端发送一次性消息 服务器定期向客户端发送消息 从客户端接收消息时,通过日志记录消息并将其发送回客户端 客户端向服务器发送非周期性消息 客户端接收来自服务器的消息并将其输出到日志 程图如下:
5、Spring WebSocket 服务器由两部分组成。Spring WebSocket Event Handler(事件处理器)和 Spring WebSocket 配置。
5.1、Spring WebSocket 配置 在配置类上添加 @EnableWebSocket 注解,可以在 Spring 服务器中启用 WebSocket 支持。
1、概览 文件上传是现在应用中很常见的需求,从 Spring 5 开始可以通过响应式上传文件。有了响应式编程的加持,能够使用较少的线程和背压(Backpressure)机制,以非阻塞的方式进行上传。
本文将带你了解使用 WebClient(一种非阻塞、响应式的 HTTP 客户端)通过 BodyInserters 上传文件的两种不同方法。WebClient 是名为 Project Reactor 的响应式编程库的一部分。
2、使用 WebClient 上传文件 首先,在项目中添加 spring-boot-starter-webflux 依赖:
<dependency> <groupId>org.springframework.boot</groupId>. <artifactId>spring-boot-starter-webflux</artifactId> </dependency> 2.1、上传单个文件 首先,声明上传地址的 URL:
URI url = UriComponentsBuilder.fromHttpUrl(EXTERNAL_UPLOAD_URL).build().toUri(); 比方说,在本例中要上传 PDF。因此使用 MediaType.APPLICATION_PDF 作为 ContentType。上传端点会返回一个 HttpStatus。由于只希望得到一个结果,所以将其封装在一个 Mono 中:
Mono<HttpStatus> httpStatusMono = webClient.post() .uri(url) .contentType(MediaType.APPLICATION_PDF) .body(BodyInserters.fromResource(resource)) .exchangeToMono(response -> { if (response.statusCode().equals(HttpStatus.OK)) { return response.bodyToMono(HttpStatus.class).thenReturn(response.statusCode()); } else { throw new ServiceException("Error uploading file"); } }); 调用这个方法的方法也可以返回一个 Mono,可以一直进行下去,直到真正需要访问结果为止。就绪后,可以在 Mono 对象上调用 block() 方法。
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.
1、简介 所有 Java Web 框架都建立在 Servlet Api 的基础之上。在基于 Spring 开发的 Java Web 应用中,有三个文件起着至关重要的作用。通常,按以下顺序将它们串联起来:web.xml -> applicationContext.xml -> spring-servlet.xml。
本文将带你了解 applicationContext.xml 和 spring-servlet.xml 之间的区别。
2、applicationContext.xml 反转控制(IoC)是 Spring 的核心。在使用 IoC 的框架中,通常由容器负责实例化、创建和删除对象。在 Spring 中,applicationContext 就扮演着 IoC 容器的角色。
在开发标准 J2EE 应用时,会在 web.xml 文件中声明 ContextLoaderListener。此外,还定义了一个 contextConfigLocation 来指定 XML 配置文件。
<context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/applicationContext*.xml</param-value> </context-param> 应用启动时,Spring 会加载该配置文件,并使用它创建 WebApplicationContext 对象。如果没有 contextConfigLocation,默认情况下,系统将查找 /WEB-INF/applicationContext.xml 来加载。
简而言之,applicationContext 是 Spring 的核心接口。它为应用提供配置信息。
在该文件中,提供了与应用相关的配置。通常,这些配置包括基本数据源、属性占位符文件(Property Place Holder)和用于项目本地化的消息源(Message Source),以及其他增强功能。
示例如下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:c="http://www.springframework.org/schema/c" xmlns:p="http://www.
简介 本文将带你了解如何使用 Spring 和 Hibernate 实现表分区。
表分区的目标是将一个大型表分割为多个较小的分区表,以便关联的表和索引记录可以放入内存缓冲池,从而实现更高效的查找或扫描操作。
使用 PostgreSQL 进行表分区 PostgreSQL 为 表分区 提供了三种策略:
列表分区(List Partitioning) 范围分区(Range Partitioning) Hash 分区(Hash Partitioning) 本例使用列表分区,按大洲来划分数据表。
例如,users 分区如下:
CREATE TABLE users ( id bigint NOT NULL, first_name varchar(255), last_name varchar(255), registered_on timestamp(6), partition_key varchar(255), PRIMARY KEY (id, partition_key) ) PARTITION BY LIST (partition_key) CREATE TABLE users_asia PARTITION OF users FOR VALUES IN ('Asia') CREATE TABLE users_africa PARTITION OF users FOR VALUES IN ('Africa') CREATE TABLE users_north_america PARTITION OF users FOR VALUES IN ('North America') CREATE TABLE users_south_america PARTITION OF users FOR VALUES IN ('South America') CREATE TABLE users_europe PARTITION OF users FOR VALUES IN ('Europe') CREATE TABLE users_australia PARTITION OF users FOR VALUES IN ('Australia') posts 表分区如下:
概览 有时我们需要在应用中监控本地磁盘上的某个目录,在目录中的文件发生变化时(创建、编辑、删除)进行相应的处理。
在 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 列。
上一教程 介绍了如何使用 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.