路由过滤器允许以某种方式修改传入的HTTP请求或传出的HTTP响应。路由过滤器的作用域是特定的路由。Spring Cloud Gateway包括许多内置的网关过滤器工厂。

有关如何使用以下过滤器的更详细示例,请查看单元测试

1.The AddRequestHeader GatewayFilter Factory

AddRequestHeader GatewayFilter工厂接受一个namevalue 参数。下面的例子配置AddRequestHeader GatewayFilter:

例 13. application.yml

  1. spring:
  2. cloud:
  3. gateway:
  4. routes:
  5. - id: add_request_header_route
  6. uri: lb://cloud-payment-service #此处需要使用lb协议才能根据服务名进行负载均衡调用
  7. predicates: #断言必须要添加,否则报错
  8. - Path=/payment/filter/lb/** #断言,路径相匹配的进行路由
  9. filters:
  10. - AddRequestHeader=X-Request-red, blue

此清单将X-Request-red:blue 标头添加到所有匹配请求的下游请求标头。

使用cURL工具发送请求:

curl http://localhost:9527/payment/filter/lb

会返回如下数据:

请求头中的数据:blue

AddRequestHeader中能够使用用于匹配路径或主机的URI变量。URI变量可以在值中使用,并在运行时展开。下面的例子配置了一个AddRequestHeader GatewayFilter,它使用了一个URL变量:

例 14. application.yml

spring:
  cloud:
    gateway:
      routes:
      - id: add_request_header_route
        uri: lb://cloud-payment-service #此处需要使用lb协议才能根据服务名进行负载均衡调用
        predicates:
        - Path=/red/{segment}
        filters:
        - AddRequestHeader=X-Request-Red, Blue-{segment}

使用cURL工具发送请求:

curl http://localhost:9527/red/abc

会返回如下数据:

请求头中的数据:Blue-abc

2.The AddRequestParameter GatewayFilter Factory

AddRequestParameter GatewayFilter工厂需要namevalue参数。以下示例配置了AddRequestParameter GatewayFilter

例 15. application.yml

spring:
  cloud:
    gateway:
      routes:
      - id: add_request_parameter_route
        uri: lb://cloud-payment-service #此处需要使用lb协议才能根据服务名进行负载均衡调用
        predicates: #断言必须要添加,否则报错
        - Path=/payment/filter/lb/**   #断言,路径相匹配的进行路由
        filters:
        - AddRequestParameter=red, blue

这将添加red=blue到所有匹配请求的下游请求的查询字符串中。

使用cURL工具发送请求:

curl http://localhost:9527/payment/filter/lb

会返回如下数据:

获取到的参数数据:blue

AddRequestParameter中能够使用用于匹配路径或主机的URI变量。URI变量可以在值中使用,并在运行时展开。下面的例子配置了一个AddRequestParameter GatewayFilter,它使用了一个URL变量:

例 16. application.yml

spring:
  cloud:
    gateway:
      routes:
      - id: add_request_parameter_route
        uri: lb://cloud-payment-service #此处需要使用lb协议才能根据服务名进行负载均衡调用
        predicates:
        - Host: {segment}.myhost.org
        filters:
        - AddRequestParameter=foo, bar-{segment}

使用cURL工具发送请求:

curl http://localhost:9527/payment/filter/lb -H "Host:www.myhost.org"

会返回如下数据:

获取到的参数数据:bar-www

3.The AddResponseHeader GatewayFilter Factory

AddResponseHeader GatewayFilter工厂需要namevalue参数。以下示例配置了AddResponseHeader GatewayFilter

例 17. application.yml

spring:
  cloud:
    gateway:
      routes:
      - id: add_response_header_route
        uri: lb://cloud-payment-service #此处需要使用lb协议才能根据服务名进行负载均衡调用
        predicates: #断言必须要添加,否则报错
        - Path=/payment/filter/lb/**   #断言,路径相匹配的进行路由
        filters:
        - AddResponseHeader=X-Response-Red, Blue

这会将X-Response-Red:Blue标头添加到所有匹配请求的下游响应的标头中。

使用cURL工具发送请求:

curl -I http://localhost:9527/payment/filter/lb

如下是响应头中的数据,可以看到X-Response-Red: Blue

HTTP/1.1 200 OK
X-Response-Red: Blue
Content-Type: text/plain;charset=UTF-8
Content-Length: 4
Date: Fri, 29 May 2020 04:19:54 GMT

AddResponseHeader中能够使用用于匹配路径或主机的URI变量。URI变量可以在值中使用,并在运行时展开。下面的例子配置了一个AddResponseHeader GatewayFilter,它使用了一个URL变量:

例 18. application.yml

spring:
  cloud:
    gateway:
      routes:
      - id: add_response_header_route
        uri: lb://cloud-payment-service #此处需要使用lb协议才能根据服务名进行负载均衡调用
        predicates:
        - Host: {segment}.myhost.org
        filters:
        - AddResponseHeader=foo, bar-{segment}

使用cURL工具发送请求:

curl -I http://localhost:9527/payment/filter/lb -H "Host:www.myhost.org"

如下是响应头中的数据,可以看到 foo:bar-www

HTTP/1.1 200 OK
foo: bar-www
Content-Type: text/plain;charset=UTF-8
Content-Length: 4
Date: Fri, 29 May 2020 04:16:09 GMT

4.The DedupeResponseHeader GatewayFilter Factory

DedupeResponseHeader GatewayFilter工厂采用一个name参数和一个可选strategy参数。name可以包含以空格分隔的标题名称列表。以下示例配置了DedupeResponseHeader GatewayFilter

例 19. application.yml

spring:
  cloud:
    gateway:
      routes:
      - id: dedupe_response_header_route
        uri: lb://cloud-payment-service #此处需要使用lb协议才能根据服务名进行负载均衡调用
        predicates: #断言必须要添加,否则报错
        - Path=/payment/filter/lb/**   #断言,路径相匹配的进行路由
        filters:
        - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin

**
当网关CORS逻辑和下游逻辑都将它们添加时,这将删除Access-Control-Allow-CredentialsAccess-Control-Allow-Origin响应头的重复值。

演示案例,配置重复的Access-Control-Allow-CredentialsAccess-Control-Allow-Origin

spring:
  cloud:
    gateway:
      routes:
      - id: dedupe_response_header_route
        uri: lb://cloud-payment-service #此处需要使用lb协议才能根据服务名进行负载均衡调用
        predicates: #断言必须要添加,否则报错
        - Path=/payment/filter/lb/**   #断言,路径相匹配的进行路由
        filters:
        - AddResponseHeader=Access-Control-Allow-Credentials, true
        - AddResponseHeader=Access-Control-Allow-Credentials, true
        - AddResponseHeader=Access-Control-Allow-Origin, 127.0.0.1:9527
        - AddResponseHeader=Access-Control-Allow-Origin, 127.0.0.1:9527

使用cURL工具发送请求:

curl -I http://localhost:9527/payment/filter/lb

如下是响应头中的数据,可以看到有重复的Access-Control-Allow-CredentialsAccess-Control-Allow-Origin

HTTP/1.1 200 OK
Access-Control-Allow-Credentials: true
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: 127.0.0.1:9527
Access-Control-Allow-Origin: 127.0.0.1:9527
Content-Type: text/plain;charset=UTF-8
Content-Length: 4
Date: Fri, 29 May 2020 04:46:01 GMT

添加 - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin** **配置

spring:
  cloud:
    gateway:
      routes:
      - id: dedupe_response_header_route
        uri: lb://cloud-payment-service #此处需要使用lb协议才能根据服务名进行负载均衡调用
        predicates: #断言必须要添加,否则报错
        - Path=/payment/filter/lb/**   #断言,路径相匹配的进行路由
        filters:
        - AddResponseHeader=Access-Control-Allow-Credentials, true
        - AddResponseHeader=Access-Control-Allow-Credentials, true
        - AddResponseHeader=Access-Control-Allow-Origin, 127.0.0.1:9527
        - AddResponseHeader=Access-Control-Allow-Origin, 127.0.0.1:9527
        - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin

使用cURL工具发送请求:

curl -I http://localhost:9527/payment/filter/lb

如下是响应头中的数据,可以看到已经把重复的删除了

HTTP/1.1 200 OK
Content-Type: text/plain;charset=UTF-8
Content-Length: 4
Date: Fri, 29 May 2020 04:50:38 GMT
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: 127.0.0.1:9527

DedupeResponseHeader过滤器还接受一个可选的strategy参数。可接受的值为RETAIN_FIRST(默认值)RETAIN_LAST,和RETAIN_UNIQUE

演示strategy参数配置:

  1. RETAIN_FIRST(默认值,保留第一)
  2. RETAIN_LAST(保留最后一个)
  3. RETAIN_UNIQUE(保留独特的) ```yaml spring: cloud: gateway: routes:
    • id: dedupe_response_header_route uri: lb://cloud-payment-service #此处需要使用lb协议才能根据服务名进行负载均衡调用 predicates: #断言必须要添加,否则报错
      • Path=/payment/filter/lb/** #断言,路径相匹配的进行路由 filters:
      • AddResponseHeader=Access-Control-Allow-Credentials, true
      • AddResponseHeader=Access-Control-Allow-Credentials, false
      • AddResponseHeader=Access-Control-Allow-Origin, 127.0.0.1:9527
      • AddResponseHeader=Access-Control-Allow-Origin, 127.0.0.1:9527
      • DedupeResponseHeader=Access-Control-Allow-Credentials, RETAIN_LAST
      • DedupeResponseHeader=Access-Control-Allow-Credentials, RETAIN_UNIQUE
#######################响应头为:

Access-Control-Allow-Credentials: false Control-Allow-Origin: 127.0.0.1:9527

#

spring: cloud: gateway: routes:

  - id: dedupe_response_header_route
    uri: lb://cloud-payment-service #此处需要使用lb协议才能根据服务名进行负载均衡调用
    predicates: #断言必须要添加,否则报错
    - Path=/payment/filter/lb/**   #断言,路径相匹配的进行路由
    filters:
    - AddResponseHeader=Access-Control-Allow-Credentials, true
    - AddResponseHeader=Access-Control-Allow-Credentials, false
    - AddResponseHeader=Access-Control-Allow-Origin, 127.0.0.1:9527
    - AddResponseHeader=Access-Control-Allow-Origin, 192.168.0.1:9527
    - DedupeResponseHeader=Access-Control-Allow-Credentials, RETAIN_FIRST
    - DedupeResponseHeader=Access-Control-Allow-Credentials, RETAIN_UNIQUE
#######################响应头为:

Access-Control-Allow-Credentials: true Control-Allow-Origin: 127.0.0.1:9527 Control-Allow-Origin: 192.168.0.1:9527

<a name="EdHWI"></a>
## 5.The Hystrix GatewayFilter Factory

[Netflix已将Hystrix置于维护模式](https://cloud.spring.io/spring-cloud-netflix/multi/multi__modules_in_maintenance_mode.html)。我们建议您将[Spring Cloud CircuitBreaker网关过滤器](https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.3.RELEASE/reference/html/#spring-cloud-circuitbreaker-filter-factory)与Resilience4J一起使用,因为在将来的版本中将不再支持Hystrix。

[Hystrix](https://github.com/Netflix/Hystrix)是Netflix的一个实现[断路器模式](https://martinfowler.com/bliki/CircuitBreaker.html)的库。`Hystrix` `GatewayFilter` 允许您将断路器引入网关路由,保护您的服务免受级联故障的影响,并允许您在发生下游故障时提供后备响应。

该`Hystrix` `GatewayFilter`工厂需要一个`name`参数,该参数是`HystrixCommand`的名称。以下示例配置Hystrix `GatewayFilter`:

**例 20. application.yml**
```yaml
spring:
  cloud:
    gateway:
      routes:
      - id: hystrix_route
        uri: https://example.org
        filters:
        - Hystrix=myCommandName

这将剩下的过滤器包装在一个命令名为HystrixCommand 的myCommandName中。

Hystrix过滤器还可以接受一个可选的fallbackUri 参数。目前仅支持forward: 受计划uri支持。如果回退被调用,请求被转发到URI匹配的控制器。下面的示例配置这样的回退:

例 21. application.yml

spring:
  cloud:
    gateway:
      routes:
      - id: hystrix_route
        uri: lb://backing-service:8088
        predicates:
        - Path=/consumingserviceendpoint
        filters:
        - name: Hystrix
          args:
            name: fallbackcmd
            fallbackUri: forward:/incaseoffailureusethis
        - RewritePath=/consumingserviceendpoint, /backingserviceendpoint