天天看點

Spring WebFlux使用函數式程式設計之Filtering Handler Functions

環境:Springboot2.4.12

本篇主要内容:

  • RouterFunction中使用過濾器
  • URL處理元件

請先閱讀:

  1. 《Spring WebFlux使用函數式程式設計之HandlerFunction(1)》
  2. 《Spring WebFlux使用函數式程式設計之RouterFunction(2)》

概述

你可以通過在路由函數建構器上使用before、after或filter方法來篩選處理程式函數。通過使用注釋,你可以通過使用@ControllerAdvice、ServletFilter或兩者都可以實作類似的功能。過濾器将應用于建構器建構的所有路由。這意味着在嵌套路由中定義的過濾器不适用于“頂級”路由。例如,考慮下面的例子:

RouterFunction<ServerResponse> route = route()
    .path("/person", b1 -> b1
        .nest(accept(APPLICATION_JSON), b2 -> b2
            .GET("/{id}", handler::getPerson)
            .GET("", handler::listPeople)
            .before(request -> ServerRequest.from(request) // 1
                .header("X-RequestHeader", "Value")
                .build()))
        .POST("/person", handler::createPerson))
    .after((request, response) -> logResponse(response)) // 2
    .build();           
  1. 添加自定義請求頭的before過濾器隻應用于兩個GET路由。
  2. 記錄響應的after過濾器應用于所有路由,包括嵌套路由。

路由器建構器上的filter方法接受HandlerFilterFunction:一個接受ServerRequest和HandlerFunction并傳回ServerResponse的函數。處理程式函數參數表示鍊中的下一個元素。這通常是路由到的處理程式,但如果應用了多個過濾器,它也可以是另一個過濾器。

完整示例

處理程式句柄

@Component
public class PersonHandler {
  public ServerResponse queryPerson(ServerRequest request) throws Exception {
    System.out.println(request.headers().header("x-pack")) ;
    return ok().body(new Person(Integer.valueOf(request.pathVariable("id")), "中國")) ;
  }
	
  private Errors validate(Person person) {
    Errors errors = new BeanPropertyBindingResult(person, "person");
    validator.validate(person, errors);
    if (errors.hasErrors()) {
      return errors ; 
    }
    return null ;
  }
}           

路由配置

@Configuration
public class PersonHandlerConfiguration {
	
  @Resource
  private PersonHandler ph ;
	
  @Bean
  public RouterFunction<ServerResponse> nestPerson2() {
    return route()
      .path("/persons2", b1 -> b1
        .nest(accept(MediaType.APPLICATION_JSON), b2 -> b2
          .GET("/{id}", accept(MediaType.APPLICATION_JSON), ph::queryPerson)
          .before(request -> ServerRequest.from(request).header("x-pack", "123123").build()))
        .POST("/save", ph::save))
      .after((request, response) -> {
        System.out.println("after execution..." + response.statusCode());
        return response ;
      })
      .filter((request, next) -> {
        if (request.pathVariable("id").equals("100")) {
          return ServerResponse.ok().body("參數錯誤") ;
        } else {
          return next.handle(request) ;
        }
      })
      .build();
  }
	
}           

POJO

public class Person {
  private Integer id ;
  @NotEmpty(message = "姓名必須填寫")
  private String name ;
}           

URL處理元件

URL元件可以在Spring MVC and Spring WebFlux中都可以使用。

UriComponentsBuilder幫助從帶有變量的URI模闆建構URI,如下例所示:

UriComponents uriComponents = UriComponentsBuilder
  .fromUriString("https://pack.com/lovers/{lover}")  // 1
  .queryParam("q", "{q}")  // 2
  .encode()  // 3
  .build();  // 4
URI uri = uriComponents.expand("lover", "hcw").toUri();  // 5           
  1. 使用URI模闆的靜态工廠方法
  2. 添加或替換URI元件
  3. 請求對URI模闆和URI變量進行編碼
  4. 建立一個UriComponents
  5. 展開變量并獲得URI

以上代碼運作結果:

https://pack.com/lovers/lover?q=hcw           

上面的例子可以合并為一個鍊,并使用buildAndExpand進行縮短,如下面的例子所示:

URI uri = UriComponentsBuilder
  .fromUriString("https://pack.com/lovers/{lover}")
  .queryParam("q", "{q}")
  .encode()
  .buildAndExpand("lover", "hcw")
  .toUri();           

你可以通過直接進入URI(這意味着編碼)來進一步縮短它,如下面的例子所示:

URI uri = UriComponentsBuilder
  .fromUriString("https://pack.com/lovers/{lover}")
  .queryParam("q", "{q}")
  .build("lover", "hcw");           

你可以使用完整的URI模闆進一步縮短它,如下例所示:

URI uri = UriComponentsBuilder
  .fromUriString("https://pack.com/lovers/{lover}")
  .build("lover", "hcw");           

完畢!!!

Spring容器這些擴充點你都清楚了嗎?

Spring事務實作原理源碼分析

Spring中的@Configuration注解你真的了解嗎?

SpringBoot對Spring MVC都做了哪些事?(一)

SpringBoot對Spring MVC都做了哪些事?(二)

SpringBoot對Spring MVC都做了哪些事?(三)

SpringBoot對Spring MVC都做了哪些事?(四)

Spring WebFlux使用函數式程式設計之Filtering Handler Functions
Spring WebFlux使用函數式程式設計之Filtering Handler Functions
Spring WebFlux使用函數式程式設計之Filtering Handler Functions
Spring WebFlux使用函數式程式設計之Filtering Handler Functions