Spring Cloud Gateway 内置的過濾器工廠
内置的過濾器工廠
這裡簡單将Spring Cloud Gateway内置的所有過濾器工廠整理成了一張表格。如下:
過濾器工廠 | 作用 | 參數 |
---|---|---|
AddRequestHeader | 為原始請求添加Header | Header的名稱及值 |
AddRequestParameter | 為原始請求添加請求參數 | 參數名稱及值 |
AddResponseHeader | 為原始響應添加Header | Header的名稱及值 |
DedupeResponseHeader | 剔除響應頭中重複的值 | 需要去重的Header名稱及去重政策 |
Hystrix | 為路由引入Hystrix的斷路器保護 | 的名稱 |
FallbackHeaders | 為fallbackUri的請求頭中添加具體的異常資訊 | Header的名稱 |
PrefixPath | 為原始請求路徑添加字首 | 字首路徑 |
PreserveHostHeader | 為請求添加一個preserveHostHeader=true的屬性,路由過濾器會檢查該屬性以決定是否要發送原始的Host | 無 |
RequestRateLimiter | 用于對請求限流,限流算法為令牌桶 | keyResolver、rateLimiter、statusCode、denyEmptyKey、emptyKeyStatus |
RedirectTo | 将原始請求重定向到指定的URL | http狀态碼及重定向的url |
RemoveHopByHopHeadersFilter | 為原始請求删除IETF組織規定的一系列Header | 預設就會啟用,可以通過配置指定僅删除哪些Header |
RemoveRequestHeader | 為原始請求删除某個Header | Header名稱 |
RemoveResponseHeader | 為原始響應删除某個Header | Header名稱 |
RewritePath | 重寫原始的請求路徑 | 原始路徑正規表達式以及重寫後路徑的正規表達式 |
RewriteResponseHeader | 重寫原始響應中的某個Header | Header名稱,值的正規表達式,重寫後的值 |
SaveSession | 在轉發請求之前,強制執行 操作 | 無 |
secureHeaders | 為原始響應添加一系列起安全作用的響應頭 | 無,支援修改這些安全響應頭的值 |
SetPath | 修改原始的請求路徑 | 修改後的路徑 |
SetResponseHeader | 修改原始響應中某個Header的值 | Header名稱,修改後的值 |
SetStatus | 修改原始響應的狀态碼 | HTTP 狀态碼,可以是數字,也可以是字元串 |
StripPrefix | 用于截斷原始請求的路徑 | 使用數字表示要截斷的路徑的數量 |
Retry | 針對不同的響應進行重試 | retries、statuses、methods、series |
RequestSize | 設定允許接收最大請求包的大小。如果請求包大小超過設定的值,則傳回 | 請求包大小,機關為位元組,預設值為5M |
ModifyRequestBody | 在轉發請求之前修改原始請求體内容 | 修改後的請求體内容 |
ModifyResponseBody | 修改原始響應體的内容 | 修改後的響應體内容 |
Default | 為所有路由添加過濾器 | 過濾器工廠名稱及值 |
**Tips:**每個過濾器工廠都對應一個實作類,并且這些類的名稱必須以
GatewayFilterFactory
結尾,這是Spring Cloud Gateway的一個約定,例如
AddRequestHeader
對應的實作類為
AddRequestHeaderGatewayFilterFactory
。
1、AddRequestHeader GatewayFilter Factory
為原始請求添加Header,配置示例:
spring:
cloud:
gateway:
routes:
- id: add_request_header_route
uri: https://example.org
filters:
- AddRequestHeader=X-Request-Foo, Bar
為原始請求添加名為
X-Request-Foo
,值為
Bar
的請求頭
2、AddRequestParameter GatewayFilter Factory
為原始請求添加請求參數及值,配置示例:
spring:
cloud:
gateway:
routes:
- id: add_request_parameter_route
uri: https://example.org
filters:
- AddRequestParameter=foo, bar
為原始請求添加名為foo,值為bar的參數,即:
foo=bar
3、AddResponseHeader GatewayFilter Factory
為原始響應添加Header,配置示例:
spring:
cloud:
gateway:
routes:
- id: add_response_header_route
uri: https://example.org
filters:
- AddResponseHeader=X-Response-Foo, Bar
為原始響應添加名為
X-Request-Foo
,值為
Bar
的響應頭
4、DedupeResponseHeader GatewayFilter Factory
DedupeResponseHeader可以根據配置的Header名稱及去重政策剔除響應頭中重複的值,這是Spring Cloud Greenwich SR2提供的新特性,低于這個版本無法使用。
我們在Gateway以及微服務上都設定了CORS(解決跨域)Header的話,如果不做任何配置,那麼請求 -> 網關 -> 微服務,獲得的CORS Header的值,就将會是這樣的:
Access-Control-Allow-Credentials: true, true
Access-Control-Allow-Origin: https://musk.mars, https://musk.mars
可以看到這兩個Header的值都重複了,若想把這兩個Header的值去重的話,就需要使用到DedupeResponseHeader,配置示例:
spring:
cloud:
gateway:
routes:
- id: dedupe_response_header_route
uri: https://example.org
filters:
# 若需要去重的Header有多個,使用空格分隔
- DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin
去重政策:
- RETAIN_FIRST:預設值,保留第一個值
- RETAIN_LAST:保留最後一個值
- RETAIN_UNIQUE:保留所有唯一值,以它們第一次出現的順序保留
若想對該過濾器工廠有個比較全面的了解的話,建議閱讀該過濾器工廠的源碼,因為源碼裡有詳細的注釋及示例,比官方文檔寫得還好:
org.springframework.cloud.gateway.filter.factory.DedupeResponseHeaderGatewayFilterFactory
5、Hystrix GatewayFilter Factory
為路由引入Hystrix的斷路器保護,配置示例:
spring:
cloud:
gateway:
routes:
- id: hystrix_route
uri: https://example.org
filters:
- Hystrix=myCommandName
Hystrix是Spring Cloud第一代容錯元件,不過已經進入維護模式,未來Hystrix會被Spring Cloud移除掉,取而代之的是Alibaba Sentinel/Resilience4J。是以本文不做詳細介紹了,感興趣的話可以參考官方文檔:
- Hystrix GatewayFilter Factory
6、FallbackHeaders GatewayFilter Factory
同樣是對Hystrix的支援,上一小節所介紹的過濾器工廠支援一個配置參數:
fallbackUri
,該配置用于當發生異常時将請求轉發到一個特定的uri上。而
FallbackHeaders
這個過濾工廠可以在轉發請求到該uri時添加一個Header,這個Header的值為具體的異常資訊。配置示例:
spring:
cloud:
gateway:
routes:
- id: ingredients
uri: lb://ingredients
predicates:
- Path=//ingredients/**
filters:
- name: Hystrix
args:
name: fetchIngredients
fallbackUri: forward:/fallback
- id: ingredients-fallback
uri: http://localhost:9994
predicates:
- Path=/fallback
filters:
- name: FallbackHeaders
args:
executionExceptionTypeHeaderName: Test-Header
這裡也不做詳細介紹了,感興趣可以參考官方文檔:
- FallbackHeaders GatewayFilter Factory
7、PrefixPath GatewayFilter Factory
為原始的請求路徑添加一個字首路徑,配置示例:
spring:
cloud:
gateway:
routes:
- id: prefixpath_route
uri: https://example.org
filters:
- PrefixPath=/mypath
該配置使通路
${GATEWAY_URL}/hello
會轉發到
https://example.org/mypath/hello
8、PreserveHostHeader GatewayFilter Factory
為請求添加一個preserveHostHeader=true的屬性,路由過濾器會檢查該屬性以決定是否要發送原始的Host Header。配置示例:
spring:
cloud:
gateway:
routes:
- id: preserve_host_route
uri: https://example.org
filters:
- PreserveHostHeader
如果不設定,那麼名為
Host
的Header将由Http Client控制
9、RequestRateLimiter GatewayFilter Factory
用于對請求進行限流,限流算法為令牌桶。配置示例:
spring:
cloud:
gateway:
routes:
- id: requestratelimiter_route
uri: https://example.org
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 10
redis-rate-limiter.burstCapacity: 20
由于另一篇文章中已經介紹過如何使用該過濾器工廠實作網關限流,是以這裡就不再贅述了:
- Spring Cloud Gateway - 擴充
或者參考官方文檔:
- RequestRateLimiter GatewayFilter Factory
10、RedirectTo GatewayFilter Factory
将原始請求重定向到指定的Url,配置示例:
spring:
cloud:
gateway:
routes:
- id: redirect_route
uri: https://example.org
filters:
- RedirectTo=302, https://acme.org
該配置使通路
${GATEWAY_URL}/hello
會被重定向到
https://acme.org/hello
,并且攜帶一個
Location:http://acme.org
的Header,而傳回用戶端的HTTP狀态碼為302
注意事項:
- HTTP狀态碼應為3xx,例如301
- URL必須是合法的URL,該URL會作為
Header的值Location
11、RemoveHopByHopHeadersFilter GatewayFilter Factory
為原始請求删除IETF組織規定的一系列Header,預設删除的Header如下:
- Connection
- Keep-Alive
- Proxy-Authenticate
- Proxy-Authorization
- TE
- Trailer
- Transfer-Encoding
- Upgrade
可以通過配置去指定僅删除哪些Header,配置示例:
spring:
cloud:
gateway:
filter:
remove-hop-by-hop:
# 多個Header使用逗号(,)分隔
headers: Connection,Keep-Alive
12、RemoveRequestHeader GatewayFilter Factory
為原始請求删除某個Header,配置示例:
spring:
cloud:
gateway:
routes:
- id: removerequestheader_route
uri: https://example.org
filters:
- RemoveRequestHeader=X-Request-Foo
删除原始請求中名為
X-Request-Foo
的請求頭
13、RemoveResponseHeader GatewayFilter Factory
為原始響應删除某個Header,配置示例:
spring:
cloud:
gateway:
routes:
- id: removeresponseheader_route
uri: https://example.org
filters:
- RemoveResponseHeader=X-Response-Foo
删除原始響應中名為
X-Request-Foo
的響應頭
14、RewritePath GatewayFilter Factory
通過正規表達式重寫原始的請求路徑,配置示例:
spring:
cloud:
gateway:
routes:
- id: rewritepath_route
uri: https://example.org
predicates:
- Path=/foo/**
filters:
# 參數1為原始路徑的正規表達式,參數2為重寫後路徑的正規表達式
- RewritePath=/foo/(?<segment>.*), /$\{segment}
該配置使得通路
/foo/bar
時,會将路徑重寫為
/bar
再進行轉發,也就是會轉發到
https://example.org/bar
。需要注意的是:由于YAML文法,需用
$\
替換
$
15、RewriteResponseHeader GatewayFilter Factory
重寫原始響應中的某個Header,配置示例:
spring:
cloud:
gateway:
routes:
- id: rewriteresponseheader_route
uri: https://example.org
filters:
# 參數1為Header名稱,參數2為值的正規表達式,參數3為重寫後的值
- RewriteResponseHeader=X-Response-Foo, password=[^&]+, password=***
該配置的意義在于:如果響應頭中
X-Response-Foo
的值為
/42?user=ford&password=omg!what&flag=true
,那麼就會被按照配置的值重寫成
/42?user=ford&password=***&flag=true
,也就是把其中的
password=omg!what
重寫成了
password=***
16、SaveSession GatewayFilter Factory
在轉發請求之前,強制執行
WebSession::save
操作,配置示例:
spring:
cloud:
gateway:
routes:
- id: save_session
uri: https://example.org
predicates:
- Path=/foo/**
filters:
- SaveSession
主要用在那種像 Spring Session 延遲資料存儲(資料不是立刻持久化)的,并希望在請求轉發前確定session狀态儲存情況。如果你将Spring Secutiry于Spring Session內建使用,并想確定安全資訊都傳到下遊機器,你就需要配置這個filter。
17、secureHeaders GatewayFilter Factory
secureHeaders過濾器工廠主要是參考了這篇部落格中的建議,為原始響應添加了一系列起安全作用的響應頭。預設會添加如下Headers(包括值):
-
X-Xss-Protection:1; mode=block
-
Strict-Transport-Security:max-age=631138519
-
X-Frame-Options:DENY
-
X-Content-Type-Options:nosniff
-
Referrer-Policy:no-referrer
-
Content-Security-Policy:default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline'
-
X-Download-Options:noopen
-
X-Permitted-Cross-Domain-Policies:none
如果你想修改這些Header的值,那麼就需要使用這些Headers對應的字尾,如下:
-
xss-protection-header
-
strict-transport-security
-
frame-options
-
content-type-options
-
referrer-policy
-
content-security-policy
-
download-options
-
permitted-cross-domain-policies
配置示例:
spring:
cloud:
gateway:
filter:
secure-headers:
# 修改 X-Xss-Protection 的值為 2; mode=unblock
xss-protection-header: 2; mode=unblock
如果想禁用某些Header,可使用如下配置:
spring:
cloud:
gateway:
filter:
secure-headers:
# 多個使用逗号(,)分隔
disable: frame-options,download-options
18、SetPath GatewayFilter Factory
修改原始的請求路徑,配置示例:
spring:
cloud:
gateway:
routes:
- id: setpath_route
uri: https://example.org
predicates:
- Path=/foo/{segment}
filters:
- SetPath=/{segment}
該配置使通路
${GATEWAY_URL}/foo/bar
時會轉發到
https://example.org/bar
,也就是原本的
/foo/bar
被修改為了
/bar
19、SetResponseHeader GatewayFilter Factory
修改原始響應中某個Header的值,配置示例:
spring:
cloud:
gateway:
routes:
- id: setresponseheader_route
uri: https://example.org
filters:
- SetResponseHeader=X-Response-Foo, Bar
将原始響應中
X-Response-Foo
的值修改為
Bar
20、SetStatus GatewayFilter Factory
修改原始響應的狀态碼,配置示例:
spring:
cloud:
gateway:
routes:
- id: setstatusstring_route
uri: https://example.org
filters:
# 字元串形式
- SetStatus=BAD_REQUEST
- id: setstatusint_route
uri: https://example.org
filters:
# 數字形式
- SetStatus=401
SetStatusd的值可以是數字,也可以是字元串。但一定要是Spring
HttpStatus
枚舉類中的值。上面這兩種配置都可以傳回401這個HTTP狀态碼。
21、StripPrefix GatewayFilter Factory
用于截斷原始請求的路徑,配置示例:
spring:
cloud:
gateway:
routes:
- id: nameRoot
uri: http://nameservice
predicates:
- Path=/name/**
filters:
# 數字表示要截斷的路徑的數量
- StripPrefix=2
如上配置,如果請求的路徑為
/name/bar/foo
,那麼則會截斷成
/foo
後進行轉發 ,也就是會截斷2個路徑。
22、Retry GatewayFilter Factory
針對不同的響應進行重試,例如可以針對HTTP狀态碼進行重試,配置示例:
spring:
cloud:
gateway:
routes:
- id: retry_test
uri: http://localhost:8080/flakey
predicates:
- Host=*.retry.com
filters:
- name: Retry
args:
retries: 3
statuses: BAD_GATEWAY
可配置如下參數:
-
:重試次數retries
-
:需要重試的狀态碼,取值在statuses
中org.springframework.http.HttpStatus
-
:需要重試的請求方法,取值在methods
中org.springframework.http.HttpMethod
-
:HTTP狀态碼序列,取值在series
中org.springframework.http.HttpStatus.Series
23、RequestSize GatewayFilter Factory
設定允許接收最大請求包的大小,配置示例:
spring:
cloud:
gateway:
routes:
- id: request_size_route
uri: http://localhost:8080/upload
predicates:
- Path=/upload
filters:
- name: RequestSize
args:
# 機關為位元組
maxSize: 5000000
如果請求包大小超過設定的值,則會傳回
413 Payload Too Large
以及一個
errorMessage
24、Modify Request Body GatewayFilter Factory
在轉發請求之前修改原始請求體内容,該過濾器工廠隻能通過代碼配置,不支援在配置檔案中配置。代碼示例:
@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route("rewrite_request_obj", r -> r.host("*.rewriterequestobj.org")
.filters(f -> f.prefixPath("/httpbin")
.modifyRequestBody(String.class, Hello.class, MediaType.APPLICATION_JSON_VALUE,
(exchange, s) -> return Mono.just(new Hello(s.toUpperCase())))).uri(uri))
.build();
}
static class Hello {
String message;
public Hello() { }
public Hello(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
Tips:該過濾器工廠處于 BETA 狀态,未來API可能會變化,生産環境請慎用
25、Modify Response Body GatewayFilter Factory
可用于修改原始響應體的内容,該過濾器工廠同樣隻能通過代碼配置,不支援在配置檔案中配置。代碼示例:
@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route("rewrite_response_upper", r -> r.host("*.rewriteresponseupper.org")
.filters(f -> f.prefixPath("/httpbin")
.modifyResponseBody(String.class, String.class,
(exchange, s) -> Mono.just(s.toUpperCase()))).uri(uri)
.build();
}
Tips:該過濾器工廠處于 BETA 狀态,未來API可能會變化,生産環境請慎用
26、Default Filters
Default Filters用于為所有路由添加過濾器工廠,也就是說通過Default Filter所配置的過濾器工廠會作用到所有的路由上。配置示例:
spring:
cloud:
gateway:
default-filters:
- AddResponseHeader=X-Response-Default-Foo, Default-Bar
- PrefixPath=/httpbin
官方文檔:
- GatewayFilter Factories