教程

Spring Security LDAP 简介

1、概览 本文将带你了解如何设置 Spring Security LDAP。 LDAP、即 Lightweight Directory Access Protocol(轻量级目录访问协议)的缩写,是一种开放的、厂商中立的协议,用于通过 Web 访问目录服务。 2、Maven 依赖 所需 Maven 依赖如下: <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-ldap</artifactId> </dependency> <dependency> <groupId>org.apache.directory.server</groupId> <artifactId>apacheds-server-jndi</artifactId> <version>1.5.5</version> </dependency> 注:使用 ApacheDS 作为 LDAP 服务器,这是一个可扩展、可嵌入的目录服务器。 3、Java 配置 Spring Security Java 配置: public class SecurityConfig { @Bean ApacheDSContainer ldapContainer() throws Exception { return new ApacheDSContainer("dc=baeldung,dc=com", "classpath:users.ldif"); } @Bean LdapAuthoritiesPopulator authorities(BaseLdapPathContextSource contextSource) { String groupSearchBase = "ou=groups"; DefaultLdapAuthoritiesPopulator authorities = new DefaultLdapAuthoritiesPopulator (contextSource, groupSearchBase); authorities.setGroupSearchFilter("(member={0})"); return authorities; } @Bean AuthenticationManager authenticationManager(BaseLdapPathContextSource contextSource, LdapAuthoritiesPopulator authorities) { LdapBindAuthenticationManagerFactory factory = new LdapBindAuthenticationManagerFactory (contextSource); factory.

RestTemplate 教程

1、概览 本文将带你了解如何使用 Spring REST 客户端 RestTemplate 发起各种类型的 HTTP 请求。 2、废弃警告 从 Spring Framework 5 开始,除了 WebFlux,Spring 还引入了一个名为 WebClient 的新 HTTP 客户端。 WebClient 是一种替代 RestTemplate 的现代 HTTP 客户端。它不仅提供传统的同步 API,还支持高效的非阻塞和异步方法。 如果要开发新的应用或迁移旧的应用,最好还是使用 WebClient。在未来版本中,RestTemplate 将被弃用。 3、使用 GET 检索资源 3.1、获取纯 JSON 格式 使用 getForEntity() API 发起 GET 请求: RestTemplate restTemplate = new RestTemplate(); String fooResourceUrl = "http://localhost:8080/spring-rest/foos"; ResponseEntity<String> response = restTemplate.getForEntity(fooResourceUrl + "/1", String.class); Assertions.assertEquals(response.getStatusCode(), HttpStatus.OK); 可以访问完整的 HTTP 响应,因此可以检查 HTTP 状态码是否成功,或者处理响应体: ObjectMapper mapper = new ObjectMapper(); JsonNode root = mapper.

Spring Boot 对 CRaC(Coordinated Restore at Checkpoint)的支持

上周 发布 的 Spring 6.1 和 SpringBoot 3.2 都全面支持 CRaC(Coordinated Restore at Checkpoint)。 CRaC(Coordinated Restore at Checkpoint),翻译过来应该是 “检查点协调恢复”,如果你想了解有关 CRaC 的更多信息,请参阅 这里。 CRaC 是一个 OpenJDK 项目,可以对运行中的 JVM(Java 虚拟机)进行 “快照”,并将其状态(包括应用)存储到磁盘中。然后,在另一个时间点,可以将 JVM 从保存的检查点恢复到内存中。借助这个功能,你可以启动应用、预热并创建检查点(Checkpoint)。从保存的检查点恢复到内存主要依靠磁盘 I/O,这意味着恢复速度非常快(在毫秒级范围内)。 本文使用 SpringBoot Petclinic 项目来测试 SpringBoot 3.2 对 CRaC 的支持。 前提条件 要在 SpringBoot 3.2 中使用 CRaC,需要具备以下三个条件 支持 CRaC 的 JVM org.crac 的依赖 存放检查点的文件夹 使用的 JDK(Java 开发包)是 Azul Zulu 21.0.1 + CRaC,可从 此处 获取。该 JDK 适用于 x64 和 aarch64 CPU 架构,以及 JDK 17 和 JDK 21。

在 Spring Boot 中修改请求

1、概览 本文将带你了解如何在 HTTP 请求到达 Spring Boot 应用的 Controller 之前对其进行修改。Web 应用和 RESTful Web 服务经常使用这种方式来解决常见问题,例如在传入的 HTTP 请求到达实际 Controller 之前对其进行转换或过滤。这促进了松散耦合,大大减少了开发工作量。 2、使用 Filter 通常,应用需要执行一些通用的操作,如身份认证、日志记录、转义 HTML 字符等。Filter 是解决在任何 Servlet 容器中运行的应用的这些通用问题的最佳选择。 Filter 工作方式如下: 在 Spring Boot 应用中,以固定顺序注册 Filter,以实现以下目的: 修改请求 记录请求日志 检查请求是否经过认证或是否存在恶意脚本 决定拒绝或将请求转发给下一个 Filter 或 Controller 假设我们要转义 HTTP 请求体中的所有 HTML 字符,以防止 XSS 攻击。 首先定义 Filter: @Component @Order(1) public class EscapeHtmlFilter implements Filter { @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { filterChain.doFilter(new HtmlEscapeRequestWrapper((HttpServletRequest) servletRequest), servletResponse); } } @Order 注解中的 value 值 1 表示所有 HTTP 请求首先通过 EscapeHtmlFilter Filter。还可以在 Spring Boot 配置类中定义 FilterRegistrationBean Bean 来注册 Filter,这可以为 Filter 定义 URL 模式。

在 Spring 中实现异步重试机制

1、概览 有时,我们会通过异步的方式来提高应用的性能和响应能力。但是也需要考虑到偶尔故障的情况,如网络问题。此时,我们可以通过重试机制来重新调用。 本文将带你了解 Spring 对异步(async)和重试(retry)操作的支持以及如何在 Spring 应用中实现带有自动重试功能的异步执行。 2、Spring Boot 示例应用 构建一个简单的微服务,调用下游服务来处理一些数据。 2.1、Maven 依赖 添加 spring-boot-starter-web 依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> 2.2、实现 Spring Service 实现 EventService 类,在 processEvents 方法中调用另一个服务的方法: public String processEvents(List<String> events) { downstreamService.publishEvents(events); return "Completed"; } 定义 DownstreamService 接口: public interface DownstreamService { boolean publishEvents(List<String> events); } 3、实现带重试功能的异步执行 使用 spring-retry 来实现带有重试功能的异步执行。 3.1、添加 Retry 依赖 在 pom.xm 中添加 spring-retry 依赖: <dependency> <groupId>org.springframework.retry</groupId> <artifactId>spring-retry</artifactId> <version>2.0.4</version> </dependency> 3.2、@EnableAsync 和 @EnableRetry 配置 添加 @EnableAsync 和 @EnableRetry 注解:

Spring Boot 整合 Spring Batch

1、概览 Spring Batch 是一个强大的批处理框架,可用于开发健壮的批处理应用。 上一篇教程 介绍了 Spring Batch,本文将在此基础上带你了解如何使用 Spring Boot 设置和创建一个基本的批处理驱动应用。 2、Maven 依赖 首先,在 pom.xml 中添加 spring-boot-starter-batch 和 h2 依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-batch</artifactId> <version>3.0.0</version> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <version>2.1.214</version> <scope>runtime</scope> </dependency> 3、定义简单的 Spring Batch Job 创建一个 Job,从 CSV 文件导入 coffee 清单,使用自定义 Processor 对其进行转换,并将最终结果存储到内存数据库中。 3.1、开始 首先,程序入口: @SpringBootApplication public class SpringBootBatchProcessingApplication { public static void main(String[] args) { SpringApplication.run(SpringBootBatchProcessingApplication.class, args); } } 可以看到,这是一个标准的 Spring Boot 应用。为了简单,一切配置都是使用默认值。 在 src/main/resources/application.properties 文件中定义如下属性: file.input=coffee-list.csv 该属性包含输入 coffee 列表的位置。每一行都包含 coffee 的品牌、产地和一些特征:

Spring Batch 教程

1、概览 本文将带你深入了解 Spring Batch。它是一个批处理框架,专为执行批处理作业而设计。 当前的 5.0.0 版本支持 Spring 6 和 Java 17。 2、工作流基础 Spring Batch 遵循传统的批处理架构,其中 Job Repository 负责 Job 的调度和交互。 一项工作(Job)可以有多个步骤(Step)。每个步骤通常都遵循 读取数据、处理数据 和 写入数据 的顺序。 当然,框架会在这里完成大部分繁重的工作,尤其是在处理 Job 的底层持久化时 - 本文使用 h2 作为 Job Repository。 2.1、应用示例 在本例中,我们需要将一些财务交易数据从 CSV 迁移到 XML。 输入文件的结构非常简单。 每行包含一笔交易,由用户名(username)、用户 ID(userid)、交易日期(transaction_date)和金额(transaction_amount)组成: username, userid, transaction_date, transaction_amount devendra, 1234, 31/10/2015, 10000 john, 2134, 3/12/2015, 12321 robin, 2134, 2/02/2015, 23411 3、Maven 依赖 本项目需要依赖 Spring Core、Spring Batch 和 H2 数据库: <dependency> <groupId>org.springframework</groupId> <artifactId>spring-oxm</artifactId> <version>6.

Spring Boot 动态修改 Logger 的日志级别

在 Spring Boot 应用中,默认使用 Logback 来记录日志。可以在 application.yaml 或者是 logback-spring.xml 中配置 Logger 的日志级别。 有以下几个常见的日志级别(从低到高): TRACE(跟踪):最低级别的日志,用于输出详细的调试信息,通常用于追踪代码的执行路径。 DEBUG(调试):用于输出调试信息,帮助开发人员调试应用程序。 INFO(信息):用于输出一般性的信息,例如应用程序的启动信息、重要事件等。 WARN(警告):用于输出警告信息,表示潜在的问题或不符合预期的情况,但不会影响应用程序的正常运行。 ERROR(错误):最高级别的日志,用于输出错误信息,表示发生了一个错误或异常情况,可能会影响应用程序的正常运行。 级别越低,包含的信息越详细,级别越高,包含的信息越严重和重要。当设置日志级别时,只有达到或高于该级别的日志才会被记录和输出,而低于该级别的日志将被忽略。如:如果将日志级别设置为 INFO,则会记录和输出 INFO、WARN 和 ERROR 级别的日志,而 DEBUG 和 TRACE 级别的日志将被忽略。这有助于控制日志的详细程度和输出量,以适应特定的调试或生产环境要求。 Log4j 建议只使用 ERROR、WARN、INFO、DEBUG 四个级别。 以 ROOT Logger 的配置为例 在 application.yaml 中配置 logging: level: ROOT: DEBUG 在 logback-spring.xml 中配置 首先,需要在 application.yaml 中配置 logback-spring.xml 配置文件的位置: logging: config: classpath:logback-spring.xml 然后,在 logback-spring.xml 中配置 ROOT Logger 的日志级别: <configuration> <!-- 继承 Spring 预定义的 Logback 配置 --> <include resource="org/springframework/boot/logging/logback/base.xml"/> <!

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 Websockets 的 @SendToUser 注解

1、概览 本文将带你了解如何在 Spring WebSockets 中使用 @SendToUser 注解向特定 Session 或特定用户发送消息。 有关上述 Spring WebSockets 的介绍,请参阅 上一篇文章。 2、WebSocket 配置 首先,需要配置 Message Broker 和 WebSocket 应用端点: @Configuration @EnableWebSocketMessageBroker public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer { @Override public void configureMessageBroker(MessageBrokerRegistry config) { config.enableSimpleBroker("/topic/", "/queue/"); config.setApplicationDestinationPrefixes("/app"); } @Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/greeting"); } } 通过 @EnableWebSocketMessageBroker 注解,启用了在 WebSocket 上使用 STOMP(Streaming Text Oriented Messaging Protocol)的基于 Broker 的消息传递。需要强调的是,这个注解需要与 @Configuration 一起使用。 继承 AbstractWebSocketMessageBrokerConfigurer 并不是必须的,但这可以更容易地自定义导入的配置。 在第一个方法中,建立了一个简单的基于内存的 Message Broker,通过以 /topic 和 /queue 为前缀的目标将消息传回客户端。