Skip to content

12.4.5 Trao đổi các yêu cầu

Cho đến thời điểm này, bạn đã sử dụng phương thức retrieve() để biểu thị việc gửi một yêu cầu khi làm việc với WebClient. Trong các trường hợp đó, phương thức retrieve() trả về một đối tượng kiểu ResponseSpec, thông qua đó bạn có thể xử lý phản hồi bằng cách gọi các phương thức như onStatus(), bodyToFlux()bodyToMono(). Làm việc với ResponseSpec là ổn trong những trường hợp đơn giản, nhưng nó có một vài giới hạn. Ví dụ, nếu bạn cần truy cập vào các tiêu đề (headers) hoặc giá trị cookie của phản hồi, thì ResponseSpec sẽ không đủ đáp ứng.

Khi ResponseSpec không đáp ứng được yêu cầu, bạn có thể thử gọi exchangeToMono() hoặc exchangeToFlux() thay vì retrieve(). Phương thức exchangeToMono() trả về một Mono kiểu ClientResponse, trên đó bạn có thể áp dụng các thao tác phản ứng để kiểm tra và sử dụng dữ liệu từ toàn bộ phản hồi, bao gồm cả nội dung, tiêu đề và cookie. Phương thức exchangeToFlux() hoạt động tương tự nhưng trả về một Flux kiểu ClientResponse để làm việc với nhiều mục dữ liệu trong phản hồi.

Trước khi xem điều gì làm cho exchangeToMono()exchangeToFlux() khác biệt với retrieve(), hãy bắt đầu bằng cách xem chúng giống nhau như thế nào. Đoạn mã sau sử dụng một WebClient và exchangeToMono() để truy xuất một nguyên liệu theo ID của nguyên liệu đó:

java
Mono<Ingredient> ingredientMono = webClient
  .get()
  .uri("http://localhost:8080/ingredients/{id}", ingredientId)
  .exchangeToMono(cr -> cr.bodyToMono(Ingredient.class));

This is roughly equivalent to the next example that uses retrieve():

java
Mono<Ingredient> ingredientMono = webClient
  .get()
  .uri("http://localhost:8080/ingredients/{id}", ingredientId)
  .retrieve()
  .bodyToMono(Ingredient.class);

Trong ví dụ exchangeToMono(), thay vì sử dụng phương thức bodyToMono() của đối tượng ResponseSpec để lấy một Mono<Ingredient>, bạn sẽ nhận được một Mono<ClientResponse> mà bạn có thể áp dụng một hàm ánh xạ phẳng (flat-mapping) để ánh xạ ClientResponse thành Mono<Ingredient>, và kết quả sẽ được "làm phẳng" thành Mono trả về.

Hãy xem điều gì khiến exchangeToMono() khác biệt so với retrieve(). Giả sử rằng phản hồi từ yêu cầu có thể bao gồm một tiêu đề tên là X_UNAVAILABLE với giá trị là true để chỉ ra rằng (vì lý do nào đó) nguyên liệu đang được yêu cầu không khả dụng. Và giả sử rằng nếu tiêu đề đó tồn tại, bạn muốn Mono trả về là rỗng—tức là không trả về gì cả. Bạn có thể đạt được tình huống này bằng cách thêm một lần gọi flatMap() khác, nhưng giờ đây bạn có thể làm điều đó đơn giản hơn với một lời gọi WebClient như sau:

java
Mono<Ingredient> ingredientMono = webClient
  .get()
  .uri("http://localhost:8080/ingredients/{id}", ingredientId)
  .exchangeToMono(cr -> {
    if (cr.headers().header("X_UNAVAILABLE").contains("true")) {
      return Mono.empty();
    }
    return Mono.just(cr);
  })
  .flatMap(cr -> cr.bodyToMono(Ingredient.class));

Lần gọi flatMap() mới sẽ kiểm tra tiêu đề của đối tượng ClientRequest đã cho, tìm kiếm tiêu đề có tên X_UNAVAILABLE với giá trị true. Nếu tìm thấy, nó trả về một Mono rỗng. Ngược lại, nó trả về một Mono mới chứa ClientResponse. Trong cả hai trường hợp, Mono được trả về sẽ được "làm phẳng" vào Mono mà lần gọi flatMap() tiếp theo sẽ hoạt động trên đó.

Released under the MIT License.