環境:Springboot2.4.12
本篇主要内容:
- RouterFunction中使用過濾器
- URL處理元件
請先閱讀:
- 《Spring WebFlux使用函數式程式設計之HandlerFunction(1)》
- 《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();
- 添加自定義請求頭的before過濾器隻應用于兩個GET路由。
- 記錄響應的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
- 使用URI模闆的靜态工廠方法
- 添加或替換URI元件
- 請求對URI模闆和URI變量進行編碼
- 建立一個UriComponents
- 展開變量并獲得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都做了哪些事?(四)