Spring Cloud Gateway 內置的過濾器工廠

本文基於Spring Cloud Greenwich SR2html

[TOC]java


內置的過濾器工廠

這裏簡單將Spring Cloud Gateway內置的全部過濾器工廠整理成了一張表格,雖然不是很詳細,但能做爲速覽使用。以下:正則表達式

過濾器工廠 做用 參數
AddRequestHeader 爲原始請求添加Header Header的名稱及值
AddRequestParameter 爲原始請求添加請求參數 參數名稱及值
AddResponseHeader 爲原始響應添加Header Header的名稱及值
DedupeResponseHeader 剔除響應頭中重複的值 須要去重的Header名稱及去重策略
Hystrix 爲路由引入Hystrix的斷路器保護 HystrixCommand的名稱
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 在轉發請求以前,強制執行WebSession::save操做
secureHeaders 爲原始響應添加一系列起安全做用的響應頭 無,支持修改這些安全響應頭的值
SetPath 修改原始的請求路徑 修改後的路徑
SetResponseHeader 修改原始響應中某個Header的值 Header名稱,修改後的值
SetStatus 修改原始響應的狀態碼 HTTP 狀態碼,能夠是數字,也能夠是字符串
StripPrefix 用於截斷原始請求的路徑 使用數字表示要截斷的路徑的數量
Retry 針對不一樣的響應進行重試 retries、statuses、methods、series
RequestSize 設置容許接收最大請求包的大小。若是請求包大小超過設置的值,則返回 413 Payload Too Large 請求包大小,單位爲字節,默認值爲5M
ModifyRequestBody 在轉發請求以前修改原始請求體內容 修改後的請求體內容
ModifyResponseBody 修改原始響應體的內容 修改後的響應體內容
Default 爲全部路由添加過濾器 過濾器工廠名稱及值

Tips:每一個過濾器工廠都對應一個實現類,而且這些類的名稱必須以GatewayFilterFactory結尾,這是Spring Cloud Gateway的一個約定,例如AddRequestHeader對應的實現類爲AddRequestHeaderGatewayFilterFactory。對源碼感興趣的小夥伴就能夠按照這個規律拼接出具體的類名,以此查找這些內置過濾器工廠的實現代碼redis


一、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 的請求頭spring

二、AddRequestParameter GatewayFilter Factory

爲原始請求添加請求參數及值,配置示例:跨域

spring:
  cloud:
    gateway:
      routes:
      - id: add_request_parameter_route
        uri: https://example.org
        filters:
        - AddRequestParameter=foo, bar

爲原始請求添加名爲foo,值爲bar的參數,即:foo=bar安全

三、AddResponseHeader GatewayFilter Factory

爲原始響應添加Header,配置示例:bash

spring:
  cloud:
    gateway:
      routes:
      - id: add_response_header_route
        uri: https://example.org
        filters:
        - AddResponseHeader=X-Response-Foo, Bar

爲原始響應添加名爲 X-Request-Foo ,值爲 Bar 的響應頭session

四、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

五、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。因此本文不作詳細介紹了,感興趣的話能夠參考官方文檔:

六、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

這裏也不作詳細介紹了,感興趣能夠參考官方文檔:

七、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

八、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控制

九、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

因爲另外一篇文章中已經介紹過如何使用該過濾器工廠實現網關限流,因此這裏就再也不贅述了:

或者參考官方文檔:

十、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會做爲Location Header的值

十一、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

十二、RemoveRequestHeader GatewayFilter Factory

爲原始請求刪除某個Header,配置示例:

spring:
  cloud:
    gateway:
      routes:
      - id: removerequestheader_route
        uri: https://example.org
        filters:
        - RemoveRequestHeader=X-Request-Foo

刪除原始請求中名爲 X-Request-Foo 的請求頭

1三、RemoveResponseHeader GatewayFilter Factory

爲原始響應刪除某個Header,配置示例:

spring:
  cloud:
    gateway:
      routes:
      - id: removeresponseheader_route
        uri: https://example.org
        filters:
        - RemoveResponseHeader=X-Response-Foo

刪除原始響應中名爲 X-Request-Foo 的響應頭

1四、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語法,需用$\ 替換 $

1五、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=***

1六、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。

1七、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

1八、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

1九、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狀態碼。

2一、StripPrefix GatewayFilter Factory

用於截斷原始請求的路徑,配置示例:

spring:
  cloud:
    gateway:
      routes:
      - id: nameRoot
        uri: http://nameservice
        predicates:
        - Path=/name/**
        filters:
        # 數字表示要截斷的路徑的數量
        - StripPrefix=2

如上配置,若是請求的路徑爲 /name/bar/foo ,那麼則會截斷成/foo後進行轉發 ,也就是會截斷2個路徑。

2二、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
  • series:HTTP狀態碼序列,取值在 org.springframework.http.HttpStatus.Series

2三、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

2四、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可能會變化,生產環境請慎用

2五、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可能會變化,生產環境請慎用

2六、Default Filters

Default Filters用於爲全部路由添加過濾器工廠,也就是說經過Default Filter所配置的過濾器工廠會做用到全部的路由上。配置示例:

spring:
  cloud:
    gateway:
      default-filters:
      - AddResponseHeader=X-Response-Default-Foo, Default-Bar
      - PrefixPath=/httpbin

官方文檔:

相關文章
相關標籤/搜索