predicate簡介
電子商務平臺原始碼請加企鵝求求:一零三八七七四六二六。Predicate來自於java8的介面。Predicate 接受一個輸入引數,返回一個布林值結果。該介面包含多種預設方法來將Predicate組合成其他複雜的邏輯(比如:與,或,非)。可以用於介面請求引數校驗、判斷新老資料是否有變化需要進行更新操作。add–與、or–或、negate–非。
Spring Cloud Gateway內建了許多Predict,這些Predict的原始碼在org.springframework.cloud.gateway.handler.predicate包中,如果讀者有興趣可以閱讀一下。
predicate實戰
現在以案例的形式來講解predicate,本文中的案例基本來源於官方文件,官方文件地址:cloud.spring.io/spring-clou… ;
建立一個工程,在工程的pom檔案引入spring cloud gateway 的起步依賴spring-cloud-starter-gateway,spring cloud版本和spring boot版本,程式碼如下:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
複製程式碼
After Route Predicate Factory
AfterRoutePredicateFactory,可配置一個時間,當請求的時間在配置時間之後,才交給 router去處理。否則則報錯,不通過路由。
在工程的application.yml配置如下:
server:
port: 8081
spring:
profiles:
active: after_route
---
spring:
cloud:
gateway:
routes:
- id: after_route
uri: http://httpbin.org:80/get
predicates:
- After=2017-01-20T17:42:47.789-07:00[America/Denver]
profiles: after_route
複製程式碼
在上面的配置檔案中,配置了服務的埠為8081,配置spring.profiles.active:after_route指定了程式的spring的啟動檔案為after_route檔案。在application.yml再建一個配置檔案,語法是三個橫線,在此配置檔案中通過spring.profiles來配置檔名,和spring.profiles.active一致,然後配置spring cloud gateway 相關的配置,id標籤配置的是router的id,每個router都需要一個唯一的id,uri配置的是將請求路由到哪裡,本案例全部路由到http://httpbin.org:80/get。
predicates:
After=2017-01-20T17:42:47.789-07:00[America/Denver] 會被解析成PredicateDefinition物件 (name =After ,args= 2017-01-20T17:42:47.789-07:00[America/Denver])。在這裡需要注意的是predicates的After這個配置,遵循的契約大於配置的思想,它實際被AfterRoutePredicateFactory這個類所處理,這個After就是指定了它的Gateway web handler類為AfterRoutePredicateFactory,同理,其他型別的predicate也遵循這個規則。
當請求的時間在這個配置的時間之後,請求會被路由到http://httpbin.org:80/get。
啟動工程,在瀏覽器上訪問http://localhost:8081/,會顯示http://httpbin.org:80/get返回的結果,此時gateway路由到了配置的uri。如果我們將配置的時間設定到當前時之後,瀏覽器會顯示404,此時證明沒有路由到配置的uri.
跟時間相關的predicates還有Before Route Predicate Factory、Between Route Predicate Factory,讀者可以自行查閱官方文件,再次不再演示。
Header Route Predicate Factory
Header Route Predicate Factory需要2個引數,一個是header名,另外一個header值,該值可以是一個正規表示式。當此斷言匹配了請求的header名和值時,斷言通過,進入到router的規則中去。
在工程的配置檔案加上以下的配置:
spring:
profiles:
active: header_route
---
spring:
cloud:
gateway:
routes:
- id: header_route
uri: http://httpbin.org:80/get
predicates:
- Header=X-Request-Id, \d+
profiles: header_route
複製程式碼
在上面的配置中,當請求的Header中有X-Request-Id的header名,且header值為數字時,請求會被路由到配置的 uri. 使用curl執行以下命令:
$ curl -H 'X-Request-Id:1' localhost:8081
複製程式碼
執行命令後,會正確的返回請求結果,結果省略。如果在請求中沒有帶上X-Request-Id的header名,並且值不為數字時,請求就會報404,路由沒有被正確轉發。
Cookie Route Predicate Factory
Cookie Route Predicate Factory需要2個引數,一個時cookie名字,另一個時值,可以為正規表示式。它用於匹配請求中,帶有該名稱的cookie和cookie匹配正規表示式的請求。
在配置檔案新增以下配置:
spring:
profiles:
active: cookie_route
---
spring:
cloud:
gateway:
routes:
- id: cookie_route
uri: http://httpbin.org:80/get
predicates:
- Cookie=name, forezp
profiles: cookie_route
複製程式碼
在上面的配置中,請求帶有cookie名為 name, cookie值為forezp 的請求將都會轉發到uri為 httpbin.org:80/get的地址上。 使用curl命令進行請求,在請求中帶上 cookie,會返回正確的結果,否則,請求報404錯誤。
$ curl -H 'Cookie:name=forezp' localhost:8081
Host Route Predicate Factory
Host Route Predicate Factory需要一個引數即hostname,它可以使用. * 等去匹配host。這個引數會匹配請求頭中的host的值,一致,則請求正確轉發。
在工程的配置檔案,加上以下配置:
spring:
profiles:
active: host_route
---
spring:
cloud:
gateway:
routes:
- id: host_route
uri: http://httpbin.org:80/get
predicates:
- Host=**.fangzhipeng.com
profiles: host_route
複製程式碼
在上面的配置中,請求頭中含有Host為fangzhipeng.com的請求將會被路由轉發轉發到配置的uri。 啟動工程,執行以下的curl命令,請求會返回正確的請求結果:
curl -H 'Host:www.fangzhipeng.com' localhost:8081
複製程式碼
Method Route Predicate Factory
Method Route Predicate Factory 需要一個引數,即請求的型別。比如GET型別的請求都轉發到此路由。在工程的配置檔案加上以下的配置:
spring:
profiles:
active: method_route
---
spring:
cloud:
gateway:
routes:
- id: method_route
uri: http://httpbin.org:80/get
predicates:
- Method=GET
profiles: method_route
複製程式碼
在上面的配置中,所有的GET型別的請求都會路由轉發到配置的uri。使用 curl命令模擬 get型別的請求,會得到正確的返回結果。
$ curl localhost:8081
複製程式碼
使用 curl命令模擬 post請求,則返回404結果。
$ curl -XPOST localhost:8081
複製程式碼
Path Route Predicate Factory
Path Route Predicate Factory 需要一個引數: 一個spel表示式,應用匹配路徑。
在工程的配置檔案application.yml檔案中,做以下的配置:
spring:
profiles:
active: path_route
---
spring:
cloud:
gateway:
routes:
- id: path_route
uri: http://httpbin.org:80/get
predicates:
- Path=/foo/{segment}
profiles: path_route
複製程式碼
在上面的配置中,所有的請求路徑滿足/foo/{segment}的請求將會匹配並被路由,比如/foo/1 、/foo/bar的請求,將會命中匹配,併成功轉發。
使用curl模擬一個請求localhost:8081/foo/dew,執行之後會返回正確的請求結果。
$ curl localhost:8081/foo/dew
複製程式碼
Query Route Predicate Factory
Query Route Predicate Factory 需要2個引數:一個引數名和一個引數值的正規表示式。在工程的配置檔案application.yml做以下的配置:
spring:
profiles:
active: query_route
---
spring:
cloud:
gateway:
routes:
- id: query_route
uri: http://httpbin.org:80/get
predicates:
- Query=foo, ba.
profiles: query_route
複製程式碼
在上面的配置檔案中,配置了請求中含有引數foo,並且foo的值匹配ba.,則請求命中路由,比如一個請求中含有引數名為foo,值的為bar,能夠被正確路由轉發。
模擬請求的命令如下:
$ curl localhost:8081?foo=bar
複製程式碼
Query Route Predicate Factory也可以只填一個引數,填一個引數時,則只匹配引數名,即請求的引數中含有配置的引數名,則命中路由。比如以下的配置中,配置了請求引數中含有引數名為foo 的引數將會被請求轉發到uri為http://httpbin.org:80/get。
spring:
cloud:
gateway:
routes:
- id: query_route
uri: http://httpbin.org:80/get
predicates:
- Query=foo
profiles: query_route
複製程式碼
總結
在本篇文章中,首先介紹了Spring Cloud Gateway的工作流程和原理,然後介紹了gateway框架內建的predict及其分類,最後以案例的形式重點講解了幾個重要的Predict。Predict作為斷言,它決定了請求會被路由到哪個router 中。在斷言之後,請求會被進入到filter過濾器的邏輯,下篇文章將會為大家介紹Spring Cloud Gateway過濾器相關的內容。