Spring Webflux 构建响应式 Restful Web 服务
Posted carl-zhao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring Webflux 构建响应式 Restful Web 服务相关的知识,希望对你有一定的参考价值。
本指南将引导您完成创建“Hello, Spring!”使用Spring WebFlux的rest式web服务(Spring Boot 2.0的新版本),然后使用WebClient使用该服务(Spring Boot 2.0的新版本)。
1、你将建立什么
您将使用 Spring Webflux 和该服务的 WebClient
使用者构建一个RESTful web 服务。您将能够在两个系统中看到输出。和:
http://localhost:8080/hello
2、你需要什么
- 大约15分钟
- 最喜欢的文本编辑器或IDE
- JDK 1.8及以上版本
- Gradle 4+或Maven 3.2+
- 你也可以将代码直接导入到你的IDE中:
- Spring Tool Suite (STS)
- IntelliJ IDEA
3、如何完成本指南
与大多数 Spring Getting Started 指南一样,您可以从头开始并完成每个步骤,也可以跳过您已经熟悉的基本设置步骤。无论哪种方式,您最终都会得到可工作的代码。
要从头开始,请转到“ 从 Spring Initializr 开始”。
要跳过这些基本步骤,请执行以下步骤:
- 下载并解压缩本指南的源代码库,或者使用 Git 克隆它: git clone https://github.com/spring-guides/gs-reactive-rest-service.git
- 通过
cd
命令到达gs-reactive-rest-service/initial
- 跳转到创建 WebFlux 处理程序。
当您完成时,您可以检查您的结果与代码 gs-reactive-rest-service/complete
.
4、从 Spring Initializr 开始
您可以使用这个 预先初始化的项目 并单击 Generate 下载ZIP文件。该项目被配置为适合本教程中的示例。
手动初始化项目:
- 导航到
https://start.spring.io
。这个服务会拉入应用程序所需的所有依赖项,并为你完成大部分设置工作。 - 选择 Gradle 或 Maven 和你想要使用的语言。本指南假设您选择了Java。
- 单击
Dependencies
并选择Spring Reactive Web
。 - 点击
Generate
。 - 下载得到的ZIP文件,它是用您的选择配置的web应用程序的存档文件。
5、创建 WebFlux Handler
我们将从一个 Greeting
POJO开始,它将被我们的RESTful服务序列化为JSON:
src/main/java/hello/Greeting.java
package hello;
public class Greeting
private String message;
public Greeting()
public Greeting(String message)
this.message = message;
public String getMessage()
return this.message;
public void setMessage(String message)
this.message = message;
@Override
public String toString()
return "Greeting" +
"message='" + message + '\\'' +
'';
在 Spring Reactive 方法中,我们使用一个处理程序来处理请求并创建响应,如下所示:
src/main/java/hello/GreetingHandler.java
package hello;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;
@Component
public class GreetingHandler
public Mono<ServerResponse> hello(ServerRequest request)
return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(new Greeting("Hello, Spring!")));
这个简单的响应式类总是返回一个带有 “Hello, Spring!” “问候。它可以返回许多其他内容,包括从数据库中返回的项流、由计算生成的项流等等。注意反应性代码:保存 ServerResponse
主体的 Mono
对象。
6、创建 Router
在这个应用程序中,我们使用一个路由器来处理我们暴露的唯一路由(/hello
),如下所示:
src/main/java/hello/GreetingRouter.java
package hello;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerResponse;
import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
import static org.springframework.web.reactive.function.server.RequestPredicates.accept;
@Configuration(proxyBeanMethods = false)
public class GreetingRouter
@Bean
public RouterFunction<ServerResponse> route(GreetingHandler greetingHandler)
return RouterFunctions
.route(GET("/hello").and(accept(MediaType.APPLICATION_JSON)), greetingHandler::hello);
7、创建 WebClient
Spring RestTemplate
类本质上是阻塞的。因此,我们不希望在响应式应用程序中使用它。对于响应式应用程序,Spring 提供了 WebClient
类,它是非阻塞的。我们使用一个基于 webclient 的实现来消费我们的 RESTful 服务:
src/main/java/hello/GreetingClient.java
package hello;
import reactor.core.publisher.Mono;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;
@Component
public class GreetingClient
private final WebClient client;
// Spring Boot auto-configures a `WebClient.Builder` instance with nice defaults and customizations.
// We can use it to create a dedicated `WebClient` for our component.
public GreetingClient(WebClient.Builder builder)
this.client = builder.baseUrl("http://localhost:8080").build();
public Mono<String> getMessage()
return this.client.get().uri("/hello").accept(MediaType.APPLICATION_JSON)
.retrieve()
.bodyToMono(Greeting.class)
.map(Greeting::getMessage);
WebClient
类使用响应式特性,以 Mono
的形式保存消息的内容(由getMessage
方法返回)。这是使用函数 API (而不是命令式 API)来链接反应操作符。
适应响应式api可能需要一些时间,但是 WebClient
有一些有趣的特性,也可以在传统的 Spring MVC 应用程序中使用。
也可以使用WebClient与非响应式、阻塞式服务通信。
8、使应用程序可执行
我们将使用 main()
方法来驱动应用程序,并从端点获得 Greeting
消息。
src/main/java/hello/Application.java
package hello;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class Application
public static void main(String[] args)
ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
GreetingClient greetingClient = context.getBean(GreetingClient.class);
// We need to block for the content here or the JVM might exit before the message is logged
System.out.println(">> message = " + greetingClient.getMessage().block());
@SpringBootApplication
是一个方便的注释,它添加了以下所有内容:
@Configuration
:将类标记为应用程序上下文的 bean 定义源。@EnableAutoConfiguration
:告诉 Spring Boot 根据类路径设置、其他 bean 和各种属性设置开始添加bean。例如,如果spring-webmvc
在类路径上,这个注释将应用程序标记为web
应用程序,并激活关键行为,例如设置DispatcherServlet
。@ComponentScan
:告诉 Spring 在 hello 包中查找其他组件、配置和服务,让它找到控制器。
main()
方法使用 Spring Boo t的 SpringApplication.run()
方法来启动应用程序。您是否注意到没有一行 XML ,也没有 web.xml
文件。这个 web 应用程序是 100% 纯 Java,你不需要处理配置任何管道或基础设施。
9、构建一个可执行的JAR
您可以使用Gradle或Maven从命令行运行应用程序。您还可以构建一个单独的可执行JAR文件,其中包含所有必要的依赖项、类和资源,并运行它。构建一个可执行的jar使得在整个开发生命周期、跨不同的环境等过程中,将服务作为应用程序来交付、版本和部署变得容易。
如果你使用Gradle,你可以使用 ./gradlew boorun
来运行应用程序。或者,你也可以使用 ./gradlew build
构建JAR文件,然后运行JAR文件,如下所示:
java -jar build/libs/gs-reactive-rest-service-0.1.0.jar
如果你使用Maven,你可以使用 ./mvnw spring-boot:run
来运行这个应用。或者,您也可以使用 ./mvnw clean
包构建JAR文件,然后运行 JAR 文件,如下所示:
java -jar target/gs-reactive-rest-service-0.1.0.jar
显示日志输出。服务应该在几秒钟内启动并运行。
一旦服务启动,你会看到一行代码:
>> message = Hello, Spring!
这一行来自 WebClient
正在使用的响应式内容。当然,您可以对输出进行更有趣的处理,而不是将其放入 System.out
中。
10、测试应用程序
现在应用程序正在运行,您可以对其进行测试。首先,您可以打开浏览器并访问 http://localhost:8080/hello
,并看到 “Hello, Spring!”
在本指南中,我们还创建了一个测试类,让您开始使用 WebTestClient
类进行测试。
src/test/java/hello/GreetingRouterTest.java
package hello;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.reactive.server.WebTestClient;
import static org.assertj.core.api.Assertions.assertThat;
@ExtendWith(SpringExtension.class)
// We create a `@SpringBootTest`, starting an actual server on a `RANDOM_PORT`
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class GreetingRouterTest
// Spring Boot will create a `WebTestClient` for you,
// already configure and ready to issue requests against "localhost:RANDOM_PORT"
@Autowired
private WebTestClient webTestClient;
@Test
public void testHello()
webTestClient
// Create a GET request to test an endpoint
.get().uri("/hello")
.accept(MediaType.APPLICATION_JSON)
.exchange()
// and use the dedicated DSL to test assertions against the response
.expectStatus().isOk()
.expectBody(Greeting.class).value(greeting ->
assertThat(greeting.getMessage()).isEqualTo("Hello, Spring!");
);
11、总结
恭喜你! 您已经开发了一个响应式 Spring 应用程序,其中包括一个使用RESTful 服务的 WebClient !
想要编写新的指南或对现有指南做出贡献吗?请查看我们的 投稿指南。
以上是关于Spring Webflux 构建响应式 Restful Web 服务的主要内容,如果未能解决你的问题,请参考以下文章
Spring Webflux 构建响应式 Restful Web 服务
Spring Webflux 构建响应式 Restful Web 服务
WebFlux+Spring Data Reactive,从头到脚构建一个响应式的微服务
Spring WebFlux快速上手——响应式Spring的道法术器