【翻譯】Spring 5 WebFlux入門
技術標籤:翻譯spring boot
1. 概覽
Spring WebFlux 框架是 Spring 5的一部分,他為 web 應用提供了響應式程式設計的支援。
在本文中,我們將使用響應式註解RestController和WebClient建立一個小的 REST 應用,
我們還將研究如何使用Spring Security保護我們的響應式端點。
2. Spring WebFlux 框架
Spring WebFlux內部使用Project Reactor及其釋出者實現 - Flux和Mono。
這個新框架支援下面兩種程式設計模型:
- 基於註釋的響應式元件
- 函式級別的路由和處理
在這裡,我們將重點關注基於註釋的響應式元件,正如我們已經研究過的
3. 依賴
讓我們從spring-boot-starter-webflux依賴開始,它包含了所有其他必需的依賴:
- 用於基本Spring Boot應用程式設定的spring-boot和spring-boot-starter
- spring-webflux框架
-
我們使用 reactive streams 和 reactor-netty需要的reactor-core
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> <version>2.0.3.RELEASE</version> </dependency>
最新的spring-boot-starter-webflux 可以從Maven Central下載。
4. 響應式 REST 應用
我們將使用 Spring WebFlux 來建立一個非常簡單的響應式 REST 員工管理應用:
- 我們將使用一個簡單的域模型 - 具有id和name欄位的Employee
- 我們將使用RestController和WebClient構建REST API,用於釋出和檢索Single以及Collection Employeeresources
- 我們還將使用WebFlux和Spring Security建立安全的響應式端點
5. 響應式的 RestController
Spring WebFlux和Spring Web MVC框架一樣,都支援基於註釋的配置。
首先,在伺服器端,我們建立一個帶註釋的控制器,用於釋出我們的Employee反應流。
讓我們建立帶註釋的EmployeeController:
@RestController
@RequestMapping("/employees")
public class EmployeeReactiveController {
private final EmployeeRepository employeeRepository;
// constructor...
}
EmployeeRepository可以是支援非阻塞響應流的任何資料儲存庫。
5.1. 單一資源
讓我們在控制器中建立一個釋出單個Employee資源的端點:
@GetMapping("/{id}")
private Mono<Employee> getEmployeeById(@PathVariable String id) {
return employeeRepository.findEmployeeById(id);
}
對於單個Employee資源,我們使用了Employee型別的Mono,因為它最多會發出1個元素。
5.2. 集合資源
我們還在我們的控制器中新增一個端點,用於釋出所有Employees的集合資源:
@GetMapping
private Flux<Employee> getAllEmployees() {
return employeeRepository.findAllEmployees();
}
對於集合資源,我們使用了Employee型別的Flux - 因為那是釋出者專注於發出0..n元素。
6. 響應式 web 客戶端
在Spring 5中引入的WebClient是一個支援Reactive Streams的非阻塞客戶端。
在客戶端,我們使用WebClient從EmployeeController中建立的端點檢索資料。
讓我們建立一個簡單的EmployeeWebClient:
public class EmployeeWebClient {
WebClient client = WebClient.create("http://localhost:8080");
// ...
}
這裡我們使用其工廠方法create建立了一個WebClient。 對於相對URL,它將指向localhost:8080。
6.1. 獲取單一資源
To retrieve single resource of type Mono from endpoint /employee/{id}:
從/employee/{id}中返回資源型別Mono獲取單一資源:
Mono<Employee> employeeMono = client.get()
.uri("/employees/{id}", "1")
.retrieve()
.bodyToMono(Employee.class);
employeeMono.subscribe(System.out::println);
6.2. 獲取集合資源
同樣的,通過/employees中返回資源型別Flux來獲取集合資源:
Flux<Employee> employeeFlux = client.get()
.uri("/employees")
.retrieve()
.bodyToFlux(Employee.class);
employeeFlux.subscribe(System.out::println);
詳細的說明參考這篇文章 setting up and working with WebClient.
7. Spring WebFlux Security
我們可以使用 Spring Security 來對我們的響應式端點進行加密.
假設我們的EmployeeController中有一個新的端點。 此端點更新Employee詳細資訊並返回更新後的Employee。
由於這允許使用者更改現有員工,因此我們希望僅將此端點限制為ADMIN角色使用者。
讓我們為EmployeeController新增一個新方法:
@PostMapping("/update")
private Mono<Employee> updateEmployee(@RequestBody Employee employee) {
return employeeRepository.updateEmployee(employee);
}
現在,為了限制對此方法的訪問,讓我們建立SecurityConfig並定義一些基於路徑的規則來保證僅允許ADMIN使用者:
@EnableWebFluxSecurity
public class EmployeeWebSecurityConfig {
// ...
@Bean
public SecurityWebFilterChain springSecurityFilterChain(
ServerHttpSecurity http) {
http.csrf().disable()
.authorizeExchange()
.pathMatchers(HttpMethod.POST, "/employees/update").hasRole("ADMIN")
.pathMatchers("/**").permitAll()
.and()
.httpBasic();
return http.build();
}
}
此配置將限制對端點/employees/update的訪問。 因此,只有具有ADMIN角色的使用者才能訪問此端點並更新現有Employee。
最後,@EnableWebFluxSecurity註解添加了一些預設配置的Spring Security WebFlux支援。
更詳細的說明參見 configuring and working with Spring WebFlux security.
8. 總結
在本文中,我們通過建立一個小型的Reactive REST應用程式,探索瞭如何建立和使用Spring WebFlux框架支援的反應式Web元件。
我們學習瞭如何使用RestController和WebClient分別釋出和使用反應流。
我們還研究瞭如何在Spring Security的幫助下建立安全的反應端點。
除了Reactive RestController和WebClient之外,WebFlux框架還支援反應式WebSocket和相應的WebSocketClient,用於Reactive Streams的套接字樣式流。
更詳細的資料請閱讀 working with Reactive WebSocket with Spring 5.
最後,本文的所有的原始碼都可以在 Github找到。