領先一步
VMware 提供培訓和認證,助您加速進步。
瞭解更多Spring Framework 5.0 第 5 個也是最後一個里程碑版本的更新...
“Spring MVC”這個名字非常熟悉且被廣泛使用,但也許會讓一些人驚訝的是,實際上並沒有一個名為“Spring MVC”的獨立專案或分發版。它只是 Spring Framework 發行版中的一個模組,名為 `spring-webmvc`。這裡還有另一個冷知識。你知道這個模組的頂級包裡沒有“mvc”字樣嗎?它實際上叫做 `org.springframework.web.servlet`。從實際操作上講,這些都是我們不必記住的細節。重要的是,我們有一個簡短且易於記憶的名稱來指代“基於 Spring 的 Servlet 堆疊”的 Web 框架。
Spring 的響應式堆疊 Web 框架,在 5.0 版本中新增,是完全響應式且無阻塞的。它適用於使用少量執行緒進行事件迴圈式處理。它支援 Servlet 容器(Tomcat、Jetty、Servlet 3.1+),也支援非 Servlet 執行時(Netty、Undertow),因為這個堆疊的共同基礎不是 Servlet API,而是基於 Reactive Streams 和 Reactor 專案構建的無阻塞替代方案。如果您想知道,Servlet 3.1 是否能夠進行非阻塞 I/O?是的,它能夠,並且我們支援在 Servlet 3.1 容器上執行,但 Servlet API 的其餘部分是命令式的,不能在響應式、無阻塞的堆疊中使用。
到目前為止,我們一直缺乏一個專門的名稱來描述響應式 Web 堆疊,它支援 Spring MVC 註解(例如 `@Controller`、`@RequestMapping`)以及新的函數語言程式設計模型,這使得討論和清晰地對比程式設計模型和堆疊變得具有挑戰性。在我們的里程碑 5 中,`spring-web-reactive` 模組被重新命名為 `spring-webflux`——從 Spring Web Reactive API 核心的 Flux 響應式型別中汲取靈感並保持簡潔,而我們的低階響應式 HTTP 抽象則位於通用的 `spring-web` 模組中。因此,現在我們有了 `spring-webmvc` 和 `spring-webflux` 這兩個模組並排存在,我們將分別稱它們為Spring (Web) MVC 和Spring WebFlux。如果您想知道:新模組的頂級包是 `org.springframework.web.reactive`。
接下來是一些在這個領域裡的其他重要更新...
`WebClient` 是 `RestTemplate` 的響應式、非阻塞替代方案,它為響應式和Servlet 堆疊應用程式都增加了價值。它使得處理非同步和流式場景變得輕而易舉。
在 M5 中,我們進行了實質性的改進,消除了在指定請求詳細資訊和執行交換時對靜態匯入的需求。
WebClient webClient = WebClient.create();
Mono<Person> person = webClient.get()
.uri("https://:8080/persons/42")
.accept(MediaType.APPLICATION_JSON)
.exchange()
.then(response -> response.bodyToMono(Person.class));
如果所有請求都有一個通用的基本 URL,它可以一次性預先配置。
WebClient webClient = WebClient.create("https://:8080");
Mono<Person> person = webClient.get()
.uri("/persons/{id}", 42)
.accept(MediaType.APPLICATION_JSON)
.exchange()
.then(response -> response.bodyToMono(Person.class));
也可以透過 UriBuilder 獲得程式設計控制。
Mono<Person> person = webClient.get()
.uri(builder -> builder.path("/persons/{id}").build("42"))
.accept(MediaType.APPLICATION_JSON)
.exchange()
.then(response -> response.bodyToMono(Person.class));
`spring-test` 模組中的新 `WebTestClient` 是 Spring WebFlux 整合測試支援的基礎。它封裝了一個 `WebClient` 並公開了一個用於整合測試的 API。與 Spring MVC Test 中的 `MockMvc` 類似,新的測試客戶端不需要實際執行的伺服器,而是可以使用模擬的請求和響應直接繫結到 WebFlux 伺服器基礎設施:`` `java WebTestClient client = WebTestClient .bindToController(new PersonController()) .build();
client.get().uri("/persons/42") .exchange() .expectStatus().isOk() .expectHeader().contentType(MediaType.APPLICATION_JSON_UTF8) .expectBody(Person.class).value().isEqualTo(new Person("John"));
The new test client however can also run against a live server:
````java
WebTestClient client = WebTestClient
.bindToServer().baseUrl("https://:8080")
.build();
// Same test case...
流式處理也很容易測試,可以結合使用 Reactor `StepVerifier`。
FluxExchangeResult<Person> result = client.get().uri("/persons")
.accept(TEXT_EVENT_STREAM)
.exchange()
.expectStatus().isOk()
.expectHeader().contentType(TEXT_EVENT_STREAM)
.expectBody(Person.class)
.returnResult();
StepVerifier.create(result.getResponseBody())
.expectNext(new Person("Jane"), new Person("Jason"))
.expectNextCount(3)
.consumeNextWith(p -> assertEquals("John", p.getName()))
.thenCancel()
.verify();
M5 版本增加了一個新的 `PathPatternParser`,作為 `AntPathMatcher` 的替代方案,它可以使用更高效的解析模式表示來處理請求對映,並支援非常方便的 `"{*foo}"` URI 變數語法來捕獲模式末尾的任意數量的段。
作為第一步,一個新的 `ParsingPathMatcher` 實現已經允許新的 `PathPatternParser` 輕鬆地整合到 Spring MVC 和 Spring WebFlux 對映中。作為邁向 RC1 的下一步,目標是建立一個模式登錄檔,以便與請求路徑的解析表示進行匹配。
使用 Spring WebFlux 進行流式處理非常容易:`` `java @GetMapping(path = "/persons", produces = "text/event-stream") Flux
但是,應該怎麼處理
@GetMapping("/persons")
Flux<Person> getPersons() {
return this.repository.getPersons();
}
我們可以流式傳輸單個 JSON 物件,但作為一個整體,它將不是一個有效的 JSON 文件,並且瀏覽器客戶端除了使用 Server-Sent Events 或 WebSocket 之外,沒有其他方法可以消費流。
預設情況下,`Flux<Person>` 將生成一個 JSON 陣列。
[{"name":"Jane"},{"name":"John"},...]
非瀏覽器客戶端,例如 `WebClient`,可以請求 `application/stream+json` 內容型別,響應將是一個 JSON 物件流,類似於 Server-Sent Events,但沒有額外的格式。
{"name":"Jane"}
{"name":"John"}
...
我想感謝所有嘗試過 Spring Framework 5.0 並提供反饋的每個人,特別是圍繞新響應式功能的反饋。請繼續這樣做。一如既往,即使是微小的評論也可能非常有價值,因為它們讓我們從不同的角度重新審視設計選擇。
如果您本週在 DevNexus 看到這篇文章,請不要錯過機會,觀看精彩的 Josh Long 現場編碼一個響應式的 Web 應用程式,以及 Reactor 團隊核心成員 Simon Baslé 的 Reactor 3 講座。