自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

SpringMVC函數(shù)式接口Router Function,你用過嗎?

開發(fā) 前端
Spring Web MVC包括WebMvc.fn,這是一種輕量級(jí)函數(shù)式編程模型,其中函數(shù)用于路由和處理請求,參數(shù)及返回值設(shè)計(jì)為不可變。

[[437513]]

概述

Spring Web MVC包括WebMvc.fn,這是一種輕量級(jí)函數(shù)式編程模型,其中函數(shù)用于路由和處理請求,參數(shù)及返回值設(shè)計(jì)為不可變。它是基于注釋的編程模型的替代方案,但在其他方面還是運(yùn)行在同一DispatcherServlet上。

在WebMvc.fn中,HTTP請求由HandlerFunction處理:該函數(shù)接受ServerRequest并返回ServerResponse。請求和響應(yīng)對象都有不可變,提供對HTTP請求和響應(yīng)的JDK 8友好訪問。HandlerFunction相當(dāng)于基于注釋的編程模型中@RequestMapping方法的主體。

傳入的請求通過RouterFunction路由到處理程序函數(shù):一個(gè)接受ServerRequest并返回可選HandlerFunction(即可選的)的函數(shù)。當(dāng)路由器函數(shù)匹配時(shí),返回處理函數(shù);否則為空可選。RouterFunction相當(dāng)于@RequestMapping注釋,但主要區(qū)別在于路由器函數(shù)不僅提供數(shù)據(jù),還提供行為。

示例:

  1. @Configuration 
  2. public class PersonHandlerConfiguration { 
  3.      
  4.   @Bean 
  5.   public RouterFunction<ServerResponse> person() { 
  6.     return route().GET("/person", accept(MediaType.APPLICATION_JSON), request -> { 
  7.       return ServerResponse.status(HttpStatus.OK).body("Hello World") ; 
  8.     }).build() ; 
  9.   } 
  10.      

我們需要在一個(gè)@Configuration配置類中將RouterFunction暴露為Bean對象即可。

GET方法的3個(gè)參數(shù):

第一個(gè):請求的接口地址。

第二個(gè):謂詞也就是限定哪些調(diào)用能夠匹配上,這個(gè)類似注解接口@RequestMapping參數(shù)中的consumer,params等屬性一樣。

第三個(gè):HandlerFunction,這就是處理器對象了,實(shí)際的業(yè)務(wù)方法的處理對比@RequestMapping的方法體了。

HandlerFunction對象

ServerRequest和ServerResponse是不可變的接口,提供對HTTP請求和響應(yīng)的JDK8友好訪問,包括頭、正文、方法和狀態(tài)代碼。

  • ServerRequest

ServerRequest提供對HTTP方法、URI、頭和查詢參數(shù)的訪問,而對主體的訪問是通過主體方法提供的。如下示例:

  1. @Bean 
  2. public RouterFunction<ServerResponse> student() { 
  3.   return route().GET("/student/{id}", accept(MediaType.APPLICATION_JSON), request -> { 
  4.     return ServerResponse.ok().body("name = " + request.param("name").get() + ", id = " + request.pathVariable("id")) ; 
  5.   }) 
  6.   .POST("/student", accept(MediaType.APPLICATION_JSON), request -> { 
  7.     return ServerResponse.ok().body(request.body(Student.class)) ; 
  8.   }) 
  9.   .build() ; 

GET接口獲取查詢參數(shù)和路徑上的參數(shù)。

POST接口獲取body主體內(nèi)容。

  • ServerResponse

ServerResponse提供對HTTP響應(yīng)的訪問,因?yàn)樗遣豢勺兊模钥梢允褂脴?gòu)建方法來創(chuàng)建它??梢允褂蒙善髟O(shè)置響應(yīng)狀態(tài)、添加響應(yīng)標(biāo)題或提供正文。

在上面的示例中已經(jīng)看到了如何使用,這里就不再給出示例了。

  • Handler Classes處理器類

將處理器類單獨(dú)定義到一個(gè)文件中進(jìn)行相應(yīng)的處理,這就與傳統(tǒng)的@RestController注解類似了將很多的接口方法都定義在一個(gè)Controller類中。

示例:

  1. @Configuration 
  2. public class PersonHandlerConfiguration { 
  3.      
  4.   @Resource 
  5.   private PersonHandler ph ; 
  6.    
  7.   @Bean 
  8.   public RouterFunction<ServerResponse> person() { 
  9.   return route() 
  10.       .GET("/person/{id}", accept(MediaType.APPLICATION_JSON), ph::queryPerson) 
  11.       .POST("/person", accept(MediaType.APPLICATION_JSON), ph::save) 
  12.       .build() ; 
  13.   } 

 處理器類(在該類中可以注入DAO類進(jìn)行相關(guān)的數(shù)據(jù)庫操作) 

  1. @Component 
  2. public class PersonHandler { 
  3.      
  4.   public ServerResponse save(ServerRequest request) throws Exception { 
  5.     return ok().body(request.body(Person.class)) ; 
  6.   } 
  7.      
  8.   public ServerResponse queryPerson(ServerRequest request) throws Exception { 
  9.     return ok().body(new Person(Integer.valueOf(request.pathVariable("id")), "中國")) ; 
  10.   } 
  11.      
  • Validation驗(yàn)證

可以使用Spring的驗(yàn)證工具將驗(yàn)證應(yīng)用于請求主體。例如,給定一個(gè)人的自定義Spring驗(yàn)證器實(shí)現(xiàn)。示例:

  1. @Component 
  2. public class PersonHandler { 
  3.      
  4.   @Resource 
  5.   private Validator validator ; 
  6.      
  7.   public ServerResponse save(ServerRequest request) throws Exception { 
  8.     Person person = request.body(Person.class) ; 
  9.     Errors errors = validate(person) ; 
  10.     if (errors == null) { 
  11.       return ok().body(person) ; 
  12.     } 
  13.     return ok().body(errors.toString()) ; 
  14.   } 
  15.  
  16.   private Errors validate(Person person) { 
  17.     Errors errors = new BeanPropertyBindingResult(person, "person"); 
  18.     validator.validate(person, errors); 
  19.     if (errors.hasErrors()) { 
  20.       return errors ;  
  21.     } 
  22.     return null ; 
  23.   } 
  24.      

需要引入依賴:

  1. <dependency> 
  2.   <groupId>org.springframework.boot</groupId> 
  3.   <artifactId>spring-boot-starter-validation</artifactId> 
  4. </dependency>

關(guān)于參數(shù)驗(yàn)證《Springboot項(xiàng)目中你的參數(shù)都在如何驗(yàn)證?這個(gè)starter你知道嗎?》

RouterFunction

路由器功能用于將請求路由到相應(yīng)的HandlerFunction。通常,你不會(huì)自己編寫路由器函數(shù),而是使用RouterFunctions類上的方法來創(chuàng)建路由器函數(shù)。RouterFunctions.route()(無參數(shù))為你提供了創(chuàng)建路由器函數(shù)的流暢生成器,而RouterFunctions.route(RequestPredicate,HandlerFunction)則提供了創(chuàng)建路由器的直接方法。

通常,建議使用route() 構(gòu)建,因?yàn)樗鼮榈湫陀成鋱鼍疤峁┝朔奖愕慕輳?,而不需要難以發(fā)現(xiàn)的靜態(tài)導(dǎo)入。例如,router function builder提供方法GET(String,HandlerFunction)為GET請求創(chuàng)建映射;和POST(字符串、HandlerFunction)用于POST。

除了基于HTTP方法的映射之外,route builder還提供了一種在映射到請求時(shí)引入額外謂詞的方法。對于每個(gè)HTTP方法,都有一個(gè)重載變量,該變量將RequestPredicate作為參數(shù),通過它可以表示額外的約束。

在上面的示例中已經(jīng)看到了在做相應(yīng)GET,POST方法時(shí)傳的第二個(gè)參數(shù)。

  • 謂詞Predicate

我們可以編寫自己的RequestPredicate,但是RequestPredicates類提供了基于請求路徑、HTTP方法、內(nèi)容類型等的常用實(shí)現(xiàn)。如下示例通過Accept來限定了能夠接收的數(shù)據(jù)類型。

  1. import static org.springframework.web.servlet.function.RequestPredicates.accept; 
  2. @Bean 
  3. public RouterFunction<ServerResponse> hello() { 
  4.   return route().GET("/hello", accept(MediaType.APPLICATION_JSON), request -> { 
  5.     return ServerResponse.status(HttpStatus.OK).body("Hello World") ; 
  6.   }).build() ; 

 還可以通過and 或者 or 來添加多個(gè)謂詞

accept(...).and() || or()

  • 嵌套路由

在傳統(tǒng)的Controller定義時(shí),可以在類上加@RequestMapping("/person")注解的方式來統(tǒng)一請求接口的前綴。在函數(shù)式接口中我們可以通過如下的方式設(shè)定:

  1. @Bean 
  2. public RouterFunction<ServerResponse> nestPerson() { 
  3.   return route() 
  4.               .path("/persons", builder -> builder  
  5.               .GET("/{id}", accept(MediaType.APPLICATION_JSON), ph::queryPerson) 
  6.               .POST("/save", ph::save)) 
  7.                   .build(); 

 通過path定義了路由的前綴。也可以通過如下方式:

  1. @Bean 
  2. public RouterFunction<ServerResponse> nestPerson2() { 
  3.   return route() 
  4.       .path("/persons2", b1 -> b1 
  5.         .nest(accept(MediaType.APPLICATION_JSON), b2 -> b2 
  6.           .GET("/{id}", accept(MediaType.APPLICATION_JSON), ph::queryPerson)) 
  7.         .POST("/save", ph::save)) 
  8.       .build(); 

HandlerMapping

這種函數(shù)式接口既然底層還是使用的DispatcherServlet ,那么它就會(huì)有對應(yīng)的HandlerMapping和Adapter

RouterFunctionMapping:檢測Spring配置中的一個(gè)或多個(gè)RouterFunctionbean,對它們進(jìn)行排序,通過RouterFunction.andOther組合它們,并將請求路由到生成的組合RouterFunction。

HandlerFunctionAdapter:讓DispatcherHandler調(diào)用映射到請求的HandlerFunction的簡單適配器。

過濾器

可以使用路由函數(shù)生成器上的before、after或filter方法篩選處理程序函數(shù)。對于接口注釋的方式,我們可以通過使用@ControllerAdvice、ServletFilter或兩者來實(shí)現(xiàn)類似的功能。過濾器將應(yīng)用于生成器生成的所有路由。這意味著嵌套路由中定義的過濾器不適用于“頂層”路由。示例:

  1. @Bean 
  2. public RouterFunction<ServerResponse> nestPerson2() { 
  3.   return route() 
  4.         .path("/persons2", b1 -> b1 
  5.           .nest(accept(MediaType.APPLICATION_JSON), b2 -> b2 
  6.             .GET("/{id}", accept(MediaType.APPLICATION_JSON), ph::queryPerson) 
  7.             .before(request -> ServerRequest.from(request).header("x-pack""123123").build())) 
  8.           .POST("/save", ph::save)) 
  9.           .after((request, response) -> { 
  10.             System.out.println("after execution..." + response.statusCode()); 
  11.             return response ; 
  12.           }) 
  13.          .filter((request, next) -> { 
  14.            if (request.pathVariable("id").equals("100")) { 
  15.              return ServerResponse.ok().body("參數(shù)錯(cuò)誤") ; 
  16.            } else { 
  17.             return next.handle(request) ; 
  18.            } 
  19.          }) 
  20.         .build(); 
  21. public ServerResponse queryPerson(ServerRequest request) throws Exception { 
  22.   System.out.println(request.headers().header("x-pack")) ; 
  23.   return ok().body(new Person(Integer.valueOf(request.pathVariable("id")), "中國")) ; 

before:添加了自定義header信息,然后我們可以在queryPerson中獲取到,并且該before只能應(yīng)用于當(dāng)前這個(gè)嵌套的路由中。

after:能夠應(yīng)用所有的路由中

filter:filter方法采用HandlerFilterFunction:采用ServerRequest和HandlerFunction并返回ServerResponse的函數(shù)。handler函數(shù)參數(shù)表示鏈中的下一個(gè)元素。這通常是路由到的處理程序,但如果應(yīng)用了多個(gè)過濾器,它也可以是另一個(gè)過濾器。

Swagger

此時(shí)的Swagger沒有用了,所以你要慎用啊。

 

責(zé)任編輯:姜華 來源: 今日頭條
相關(guān)推薦

2023-09-09 12:23:24

函數(shù)式接口程序

2023-01-28 09:38:48

接口SpringMVC

2024-01-09 08:20:05

2023-12-22 16:39:47

Java函數(shù)式接口開發(fā)

2020-08-16 10:58:20

Pandaspython開發(fā)

2024-10-30 16:39:45

2017-10-26 08:53:38

前端JavaScript函數(shù)式編程

2020-12-31 05:49:44

FlinkSQL函數(shù)

2012-02-06 13:52:33

JavaScript

2021-11-11 08:20:47

Vue 技巧 開發(fā)工具

2024-03-11 08:21:49

2022-05-18 08:00:26

函數(shù)劫持JavaScript鉤子函數(shù)

2023-09-12 08:19:48

接口Controller線程

2022-05-05 07:25:03

Supervisor監(jiān)控Python

2021-05-07 13:39:20

Python工具代碼

2024-03-21 10:39:24

CIOAI

2025-04-03 08:00:00

灰度發(fā)布Java開發(fā)

2020-01-17 20:00:25

SQL函數(shù)數(shù)據(jù)庫

2020-09-21 14:55:15

數(shù)據(jù)庫SQL技術(shù)

2025-04-15 08:00:00

Java開發(fā)服務(wù)網(wǎng)格
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)