6. GatewayFilter
工厂
路由过滤器允许以某种方式修改传入的 HTTP 请求或传出的 HTTP 响应。路由过滤器的范围是特定的路由。Spring Cloud Gateway 包含许多内置的 GatewayFilter 工厂。
6.1. AddRequestHeader GatewayFilter 工厂
AddRequestHeader GatewayFilter工厂采用andname参数value。以下示例配置一个AddRequestHeader GatewayFilter:
示例 13.application.yml
spring:
cloud:
gateway:
routes:
- id: add_request_header_route
uri: https://example.org
filters:
- AddRequestHeader=X-Request-red, blue
此清单将X-Request-red:blue标头添加到所有匹配请求的下游请求标头中。
AddRequestHeader知道用于匹配路径或主机的 URI 变量。URI 变量可以在值中使用并在运行时扩展。以下示例配置AddRequestHeader GatewayFilter使用变量的 an:
示例 14.application.yml
spring:
cloud:
gateway:
routes:
- id: add_request_header_route
uri: https://example.org
predicates:
- Path=/red/{segment}
filters:
- AddRequestHeader=X-Request-Red, Blue-{segment}
6.2. AddRequestParameter GatewayFilter 工厂
AddRequestParameter GatewayFilterFactory 采用andname参数value。以下示例配置一个AddRequestParameter GatewayFilter:
示例 15.application.yml
spring:
cloud:
gateway:
routes:
- id: add_request_parameter_route
uri: https://example.org
filters:
- AddRequestParameter=red, blue
这将添加red=blue到所有匹配请求的下游请求的查询字符串中。
AddRequestParameter知道用于匹配路径或主机的 URI 变量。URI 变量可以在值中使用并在运行时扩展。以下示例配置AddRequestParameter GatewayFilter使用变量的 an:
示例 16.application.yml
spring:
cloud:
gateway:
routes:
- id: add_request_parameter_route
uri: https://example.org
predicates:
- Host: {segment}.myhost.org
filters:
- AddRequestParameter=foo, bar-{segment}
6.3. The AddResponseHeader GatewayFilter Factory
AddResponseHeader GatewayFilterFactory 采用andname参数value。以下示例配置一个AddResponseHeader GatewayFilter:
示例 17.application.yml
spring:
cloud:
gateway:
routes:
- id: add_response_header_route
uri: https://example.org
filters:
- AddResponseHeader=X-Response-Red, Blue
这会将X-Response-Red:Blue标头添加到所有匹配请求的下游响应标头中。
AddResponseHeader知道用于匹配路径或主机的 URI 变量。URI 变量可以在值中使用并在运行时扩展。以下示例配置AddResponseHeader GatewayFilter使用变量的 an:
示例 18.application.yml
spring:
cloud:
gateway:
routes:
- id: add_response_header_route
uri: https://example.org
predicates:
- Host: {segment}.myhost.org
filters:
- AddResponseHeader=foo, bar-{segment}
6.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: https://example.org
filters:
- DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin
在网关 CORS 逻辑和下游逻辑都添加它们的情况下,这将删除重复值Access-Control-Allow-Credentials和响应标头。Access-Control-Allow-Origin
过滤器DedupeResponseHeader还接受一个可选strategy参数。接受的值为RETAIN_FIRST(默认)RETAIN_LAST、 和RETAIN_UNIQUE。
6.5. Spring Cloud CircuitBreaker GatewayFilter Factory
Spring Cloud CircuitBreaker GatewayFilter 工厂使用 Spring Cloud CircuitBreaker API 将网关路由包装在断路器中。Spring Cloud CircuitBreaker 支持多个可与 Spring Cloud Gateway 一起使用的库。Spring Cloud 开箱即用地支持 Resilience4J。
要启用 Spring Cloud CircuitBreaker 过滤器,您需要放置spring-cloud-starter-circuitbreaker-reactor-resilience4j在类路径中。以下示例配置 Spring Cloud CircuitBreaker GatewayFilter:
示例 20.application.yml
spring:
cloud:
gateway:
routes:
- id: circuitbreaker_route
uri: https://example.org
filters:
- CircuitBreaker=myCircuitBreaker
要配置断路器,请参阅您正在使用的底层断路器实现的配置。
- Resilience4J 文档
Spring Cloud CircuitBreaker 过滤器也可以接受一个可选fallbackUri参数。目前,仅forward:支持方案化 URI。如果调用了fallback,则将请求转发到URI匹配的控制器。以下示例配置了这样的回退:
示例 21.application.yml
spring:
cloud:
gateway:
routes:
- id: circuitbreaker_route
uri: lb://backing-service:8088
predicates:
- Path=/consumingServiceEndpoint
filters:
- name: CircuitBreaker
args:
name: myCircuitBreaker
fallbackUri: forward:/inCaseOfFailureUseThis
- RewritePath=/consumingServiceEndpoint, /backingServiceEndpoint
下面的清单在 Java 中做同样的事情:
示例 22.Application.java
@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route("circuitbreaker_route", r -> r.path("/consumingServiceEndpoint")
.filters(f -> f.circuitBreaker(c -> c.name("myCircuitBreaker").fallbackUri("forward:/inCaseOfFailureUseThis"))
.rewritePath("/consumingServiceEndpoint", "/backingServiceEndpoint")).uri("lb://backing-service:8088")
.build();
}
/inCaseofFailureUseThis此示例在调用断路器回退时转发到URI。请注意,此示例还演示了(可选)Spring Cloud LoadBalancer 负载平衡(由lb目标 URI 上的前缀定义)。
主要场景是使用fallbackUri定义网关应用程序中的内部控制器或处理程序。但是,您也可以将请求重新路由到外部应用程序中的控制器或处理程序,如下所示:
示例 23.application.yml
spring:
cloud:
gateway:
routes:
- id: ingredients
uri: lb://ingredients
predicates:
- Path=//ingredients/**
filters:
- name: CircuitBreaker
args:
name: fetchIngredients
fallbackUri: forward:/fallback
- id: ingredients-fallback
uri: http://localhost:9994
predicates:
- Path=/fallback
在此示例中,网关应用程序中没有fallback端点或处理程序。但是,在另一个应用程序中有一个,在localhost:9994.
在请求被转发到回退的情况下,Spring Cloud CircuitBreaker Gateway 过滤器还提供了Throwable导致它的原因。它被添加到ServerWebExchange作为ServerWebExchangeUtils.CIRCUITBREAKER_EXECUTION_EXCEPTION_ATTR在网关应用程序中处理回退时可以使用的属性。
对于外部控制器/处理程序场景,可以添加带有异常详细信息的标头。您可以在FallbackHeaders GatewayFilter Factory 部分找到更多信息。
6.5.1. 在状态代码上使断路器跳闸
在某些情况下,您可能希望根据从其包裹的路由返回的状态代码来触发断路器。断路器配置对象采用状态代码列表,如果返回将导致断路器跳闸。在设置要使断路器跳闸的状态代码时,您可以使用带有状态代码值的整数或HttpStatus枚举的字符串表示形式。
示例 24.application.yml
spring:
cloud:
gateway:
routes:
- id: circuitbreaker_route
uri: lb://backing-service:8088
predicates:
- Path=/consumingServiceEndpoint
filters:
- name: CircuitBreaker
args:
name: myCircuitBreaker
fallbackUri: forward:/inCaseOfFailureUseThis
statusCodes:
- 500
- "NOT_FOUND"
示例 25.Application.java
@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route("circuitbreaker_route", r -> r.path("/consumingServiceEndpoint")
.filters(f -> f.circuitBreaker(c -> c.name("myCircuitBreaker").fallbackUri("forward:/inCaseOfFailureUseThis").addStatusCode("INTERNAL_SERVER_ERROR"))
.rewritePath("/consumingServiceEndpoint", "/backingServiceEndpoint")).uri("lb://backing-service:8088")
.build();
}
6.6. The FallbackHeaders GatewayFilter Factory
工厂允许您在转发到外部应用程序中FallbackHeaders的请求的标头中添加 Spring Cloud CircuitBreaker 执行异常详细信息,如以下场景所示:fallbackUri
示例 26.application.yml
spring:
cloud:
gateway:
routes:
- id: ingredients
uri: lb://ingredients
predicates:
- Path=//ingredients/**
filters:
- name: CircuitBreaker
args:
name: fetchIngredients
fallbackUri: forward:/fallback
- id: ingredients-fallback
uri: http://localhost:9994
predicates:
- Path=/fallback
filters:
- name: FallbackHeaders
args:
executionExceptionTypeHeaderName: Test-Header
在此示例中,在运行断路器时发生执行异常后,请求将被转发到fallback运行在 上的应用程序中的端点或处理程序localhost:9994。具有异常类型、消息和(如果可用)根本原因异常类型和消息的标头由FallbackHeaders过滤器添加到该请求。
您可以通过设置以下参数的值(显示为默认值)来覆盖配置中标头的名称:
-
executionExceptionTypeHeaderName ("Execution-Exception-Type")
-
executionExceptionMessageHeaderName ("Execution-Exception-Message")
-
rootCauseExceptionTypeHeaderName ("Root-Cause-Exception-Type")
-
rootCauseExceptionMessageHeaderName ("Root-Cause-Exception-Message")
有关断路器和网关的更多信息,请参阅Spring Cloud CircuitBreaker Factory 部分。
6.7. The MapRequestHeader GatewayFilter Factory
MapRequestHeader GatewayFilter工厂接受fromHeader和toHeader参数。它创建一个新的命名标头 ( ),并从传入的 http 请求中从toHeader现有的命名标头 ( ) 中提取值。fromHeader如果输入标头不存在,则过滤器没有影响。如果新的命名标头已经存在,则其值将使用新值进行扩充。以下示例配置了一个MapRequestHeader:
示例 27.application.yml
spring:
cloud:
gateway:
routes:
- id: map_request_header_route
uri: https://example.org
filters:
- MapRequestHeader=Blue, X-Request-Red
这会将X-Request-Red:
6.8. The PrefixPath GatewayFilter Factory
工厂采用PrefixPath GatewayFilter单个prefix参数。以下示例配置了一个PrefixPath GatewayFilter:
示例 28.application.yml
spring:
cloud:
gateway:
routes:
- id: prefixpath_route
uri: https://example.org
filters:
- PrefixPath=/mypath
/mypath这将作为所有匹配请求路径的前缀。因此,/hello将向 发送请求/mypath/hello。
6.9. The PreserveHostHeader GatewayFilter Factory
PreserveHostHeader GatewayFilter工厂没有参数。此过滤器设置路由过滤器检查的请求属性,以确定是否应发送原始主机头,而不是由 HTTP 客户端确定的主机头。以下示例配置了一个PreserveHostHeader GatewayFilter:
示例 29.application.yml
spring:
cloud:
gateway:
routes:
- id: preserve_host_route
uri: https://example.org
filters:
- PreserveHostHeader
6.10. The RequestRateLimiter GatewayFilter Factory
RequestRateLimiter GatewayFilter工厂使用实现RateLimiter来确定是否允许当前请求继续。如果不是,HTTP 429 - Too Many Requests则返回(默认情况下)状态。
此过滤器采用可选keyResolver参数和特定于速率限制器的参数(本节稍后描述)。
keyResolver是实现KeyResolver接口的bean。在配置中,使用 SpEL 按名称引用 bean。 #{@myKeyResolver}是一个引用名为 的 bean 的 SpEL 表达式myKeyResolver。以下清单显示了该KeyResolver界面:
示例 30.KeyResolver.java
public interface KeyResolver {
Mono<String> resolve(ServerWebExchange exchange);
}
该KeyResolver接口让可插拔策略派生出限制请求的密钥。在未来的里程碑版本中,将会有一些KeyResolver实现。
的默认实现KeyResolver是PrincipalNameKeyResolver,它Principal从ServerWebExchange和调用中检索Principal.getName()。
默认情况下,如果KeyResolver找不到密钥,则拒绝请求。spring.cloud.gateway.filter.request-rate-limiter.deny-empty-key您可以通过设置(true或false) 和spring.cloud.gateway.filter.request-rate-limiter.empty-key-status-code属性来调整此行为。
不能使用RequestRateLimiter“快捷方式”表示法进行配置。以下示例无效:
示例 32.application.properties
# 无效的快捷方式配置
spring.cloud.gateway.routes[0].filters[0]=RequestRateLimiter=2, 2, #{@userkeyresolver}
6.10.1. The Redis RateLimiter
Redis 的实现基于在Stripe完成的工作。它需要使用spring-boot-starter-data-redis-reactiveSpring Boot 启动器。
使用的算法是令牌桶算法。
该redis-rate-limiter.replenishRate属性是您希望每秒允许用户执行多少请求,而不会丢弃任何请求。这是令牌桶被填充的速率。
该redis-rate-limiter.burstCapacity属性是允许用户在一秒钟内执行的最大请求数。这是令牌桶可以容纳的令牌数量。将此值设置为零会阻止所有请求。
该redis-rate-limiter.requestedTokens属性是请求花费多少令牌。这是每个请求从存储桶中获取的令牌数,默认为1.
replenishRate通过在和中设置相同的值来实现稳定的速率burstCapacity。burstCapacity通过设置高于可以允许临时突发replenishRate。在这种情况下,需要允许速率限制器在突发之间有一段时间(根据replenishRate),因为两个连续的突发将导致请求被丢弃(HTTP 429 - Too Many Requests)。以下清单配置了一个redis-rate-limiter:
下面的速率限制1 request/s是通过设置replenishRate所需的请求数、requestedTokens以秒为单位的时间跨度以及 和burstCapacity的乘积来实现的replenishRate,requestedTokens例如设置replenishRate=1,requestedTokens=60并将burstCapacity=60导致 的限制1 request/min。
示例 32.application.yml
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
redis-rate-limiter.requestedTokens: 1
以下示例在 Java 中配置 KeyResolver:
示例 33. Config.java
@Bean
KeyResolver userKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));
}
这定义了每个用户 10 的请求速率限制。允许 20 个突发,但是在下一秒,只有 10 个请求可用。这KeyResolver是一个获取user请求参数的简单方法(注意,不建议在生产环境中这样做)。
您还可以将速率限制器定义为实现RateLimiter接口的 bean。在配置中,您可以使用 SpEL 按名称引用 bean。 #{@myRateLimiter}是一个 SpEL 表达式,它引用了一个名为 的 bean myRateLimiter。下面的清单定义了一个使用KeyResolver前面清单中定义的速率限制器:
示例 34.application.yml
spring:
cloud:
gateway:
routes:
- id: requestratelimiter_route
uri: https://example.org
filters:
- name: RequestRateLimiter
args:
rate-limiter: "#{@myRateLimiter}"
key-resolver: "#{@userKeyResolver}"
6.11. The RedirectTo GatewayFilter Factory
RedirectTo GatewayFilter工厂有两个参数,status和url。参数应为status300 系列重定向 HTTP 代码,例如 301。url参数应为有效 URL。这是Location标头的值。对于相对重定向,您应该使用uri: no://op路由定义的 uri。以下清单配置了一个RedirectTo GatewayFilter:
示例 35.application.yml
spring:
cloud:
gateway:
routes:
- id: prefixpath_route
uri: https://example.org
filters:
- RedirectTo=302, https://acme.org
这将发送带有Location:https://acme.org标头的状态 302 以执行重定向。
6.12. The RemoveRequestHeader GatewayFilter Factory
RemoveRequestHeader GatewayFilter工厂接受一个name参数。它是要删除的标头的名称。以下清单配置了一个RemoveRequestHeader GatewayFilter:
示例 36.application.yml
spring:
cloud:
gateway:
routes:
- id: removerequestheader_route
uri: https://example.org
filters:
- RemoveRequestHeader=X-Request-Foo
这会在将X-Request-Foo标头发送到下游之前将其删除。
6.13. RemoveResponseHeader GatewayFilter Factory
RemoveResponseHeader GatewayFilter工厂接受一个name参数。它是要删除的标头的名称。以下清单配置了一个RemoveResponseHeader GatewayFilter:
示例 37.application.yml
spring:
cloud:
gateway:
routes:
- id: removeresponseheader_route
uri: https://example.org
filters:
- RemoveResponseHeader=X-Response-Foo
这将X-Response-Foo在返回给网关客户端之前从响应中删除标头。
要删除任何类型的敏感标头,您应该为您可能想要这样做的任何路由配置此过滤器。此外,您可以通过使用配置此过滤器一次spring.cloud.gateway.default-filters并将其应用于所有路由。
6.14. The RemoveRequestParameter GatewayFilter Factory
RemoveRequestParameter GatewayFilter工厂接受一个name参数。它是要删除的查询参数的名称。以下示例配置了一个RemoveRequestParameter GatewayFilter:
示例 38.application.yml
spring:
cloud:
gateway:
routes:
- id: removerequestparameter_route
uri: https://example.org
filters:
- RemoveRequestParameter=red
这将在将red参数发送到下游之前将其删除。
6.15. The RewritePath GatewayFilter Factory
工厂接受一个RewritePath GatewayFilter路径regexp参数和一个replacement参数。这使用 Java 正则表达式以灵活的方式重写请求路径。以下清单配置了一个RewritePath GatewayFilter:
示例 39.application.yml
spring:
cloud:
gateway:
routes:
- id: rewritepath_route
uri: https://example.org
predicates:
- Path=/red/**
filters:
- RewritePath=/red/?(?<segment>.*), /$\{segment}
对于 的请求路径/red/blue,这会将路径设置为/blue在发出下游请求之前。请注意,由于 YAML 规范,$应将其替换为。$\
6.16. RewriteLocationResponseHeader GatewayFilter Factory
RewriteLocationResponseHeader GatewayFilter工厂修改响应头的值,Location通常是为了摆脱后端特定的细节。它需要stripVersionMode、locationHeaderName、hostValue和protocolsRegex参数。以下清单配置了一个RewriteLocationResponseHeader GatewayFilter:
示例 40.application.yml
spring:
cloud:
gateway:
routes:
- id: rewritelocationresponseheader_route
uri: http://example.org
filters:
- RewriteLocationResponseHeader=AS_IN_REQUEST, Location, ,
例如,对于 的请求, 的响应头值被重写为。POST api.example.com/some/object/nameLocationobject-service.prod.example.net/v2/some/object/idapi.example.com/some/object/id
该stripVersionMode参数具有以下可能的值:NEVER_STRIP、AS_IN_REQUEST(默认)和ALWAYS_STRIP。
-
NEVER_STRIP:版本不会被剥离,即使原始请求路径不包含版本。
-
AS_IN_REQUEST仅当原始请求路径不包含版本时,才会剥离版本。
-
ALWAYS_STRIP版本总是被剥离,即使原始请求路径包含版本。
该hostValue参数(如果提供)用于替换host:port响应Location标头的部分。如果未提供,Host则使用请求标头的值。
该protocolsRegex参数必须是有效的正则表达式String,协议名称与之匹配。如果不匹配,过滤器什么也不做。默认值为http|https|ftp|ftps。
6.17. The RewriteResponseHeader GatewayFilter Factory
RewriteResponseHeader GatewayFilter工厂采用、name和regexp参数replacement。它使用 Java 正则表达式以灵活的方式重写响应标头值。以下示例配置了一个RewriteResponseHeader GatewayFilter:
示例 41.application.yml
spring:
cloud:
gateway:
routes:
- id: rewriteresponseheader_route
uri: https://example.org
filters:
- RewriteResponseHeader=X-Response-Red, , password=[^&]+, password=***
对于 的标头值,在发出下游请求后将/42?user=ford&password=omg!what&flag=true其设置为。由于 YAML 规范,/42?user=ford&password=***&flag=true您必须使用$\
表示$
。
6.18. The SaveSession GatewayFilter Factory
工厂在将呼叫转发到下游之前SaveSession GatewayFilter强制执行WebSession::save操作。这在使用诸如带有惰性数据存储的Spring Session 之类的东西时特别有用,并且您需要确保在进行转发调用之前已保存会话状态。以下示例配置了一个:SaveSession GatewayFilter
示例 42.application.yml
spring:
cloud:
gateway:
routes:
- id: save_session
uri: https://example.org
predicates:
- Path=/foo/**
filters:
- SaveSession
如果您将Spring Security与 Spring Session 集成并希望确保安全详细信息已转发到远程进程,这很关键。
6.19. The SecureHeaders GatewayFilter Factory
根据这篇博SecureHeaders GatewayFilter文中的建议,工厂会在响应中添加一些标头。
添加了以下标题(显示为默认值):
-
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)
要更改默认值,请在spring.cloud.gateway.filter.secure-headers
命名空间中设置适当的属性。以下属性可用:
-
xss-protection-header
-
strict-transport-security
-
x-frame-options
-
x-content-type-options
-
referrer-policy
-
content-security-policy
-
x-download-options
-
x-permitted-cross-domain-policies
要禁用默认值,请spring.cloud.gateway.filter.secure-headers.disable使用逗号分隔值设置属性。以下示例显示了如何执行此操作:
spring.cloud.gateway.filter.secure-headers.disable=x-frame-options,strict-transport-security
需要使用安全标头的小写全名来禁用它。
6.20. The SetPath GatewayFilter Factory
SetPath GatewayFilter工厂采用路径参数template。它通过允许路径的模板化段提供了一种操作请求路径的简单方法。这使用来自 Spring Framework 的 URI 模板。允许多个匹配段。以下示例配置了一个SetPath GatewayFilter:
示例 43.application.yml
spring:
cloud:
gateway:
routes:
- id: setpath_route
uri: https://example.org
predicates:
- Path=/red/{segment}
filters:
- SetPath=/{segment}
对于 的请求路径/red/blue,这会将路径设置为/blue在发出下游请求之前。
6.21. The SetRequestHeader GatewayFilter Factory
SetRequestHeader GatewayFilter工厂接受name和value参数。以下清单配置了一个SetRequestHeader GatewayFilter:
示例 44.application.yml
spring:
cloud:
gateway:
routes:
- id: setrequestheader_route
uri: https://example.org
filters:
- SetRequestHeader=X-Request-Red, Blue
这GatewayFilter将替换(而不是添加)具有给定名称的所有标题。因此,如果下游服务器以 响应X-Request-Red:1234,这将被替换X-Request-Red:Blue为下游服务将接收的内容。
SetRequestHeader知道用于匹配路径或主机的 URI 变量。URI 变量可以在值中使用并在运行时扩展。以下示例配置SetRequestHeader GatewayFilter使用变量的 an:
示例 45.application.yml
spring:
cloud:
gateway:
routes:
- id: setrequestheader_route
uri: https://example.org
predicates:
- Host: {segment}.myhost.org
filters:
- SetRequestHeader=foo, bar-{segment}
6.22. The SetResponseHeader GatewayFilter Factory
SetResponseHeader GatewayFilter工厂接受name和value参数。以下清单配置了一个SetResponseHeader GatewayFilter:
示例 46.application.yml
spring:
cloud:
gateway:
routes:
- id: setresponseheader_route
uri: https://example.org
filters:
- SetResponseHeader=X-Response-Red, Blue
此 GatewayFilter 用给定名称替换(而不是添加)所有标头。因此,如果下游服务器以 响应 ,则将其X-Response-Red:1234替换为X-Response-Red:Blue,这是网关客户端将收到的。
SetResponseHeader知道用于匹配路径或主机的 URI 变量。URI 变量可以在值中使用,并将在运行时扩展。以下示例配置SetResponseHeader GatewayFilter使用变量的 an:
示例 47.application.yml
spring:
cloud:
gateway:
routes:
- id: setresponseheader_route
uri: https://example.org
predicates:
- Host: {segment}.myhost.org
filters:
- SetResponseHeader=foo, bar-{segment}
6.23. The SetStatus GatewayFilter Factory
工厂采用SetStatus GatewayFilter单个参数status. 它必须是有效的 Spring HttpStatus。它可以是整数值404或枚举的字符串表示形式:NOT_FOUND。以下清单配置了一个SetStatus GatewayFilter:
示例 48.application.yml
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
无论哪种情况,响应的 HTTP 状态都设置为 401。
您可以将其配置为SetStatus GatewayFilter在响应的标头中从代理请求返回原始 HTTP 状态代码。如果配置了以下属性,则标头将添加到响应中:
示例 49.application.yml
spring:
cloud:
gateway:
set-status:
original-status-header-name: original-http-status
6.24. The StripPrefix GatewayFilter Factory
StripPrefix GatewayFilter工厂采用一个参数,parts. 该parts参数指示在将请求发送到下游之前要从请求中剥离的路径中的部分数。以下清单配置了一个StripPrefix GatewayFilter:
示例 50.application.yml
spring:
cloud:
gateway:
routes:
- id: nameRoot
uri: https://nameservice
predicates:
- Path=/name/**
filters:
- StripPrefix=2
当通过网关向发出请求时/name/blue/red,向 发出的请求nameservice看起来像nameservice/red。
6.25. The Retry GatewayFilter Factory
-
Retry GatewayFilter工厂支持以下参数:
-
retries:应该尝试的重试次数。
-
statuses:应该重试的HTTP状态码,用 表示org.springframework.http.HttpStatus。
-
methods:应该重试的HTTP方法,用 表示org.springframework.http.HttpMethod。
-
series:要重试的一系列状态码,用 表示org.springframework.http.HttpStatus.Series。
-
exceptions:应重试的抛出异常列表。
-
backoff:为重试配置的指数退避。重试在 的退避间隔后执行firstBackoff * (factor ^ n),其中n是迭代。如果maxBackoff已配置,则应用的最大退避限制为maxBackoff. 如果basedOnPreviousValue为真,则使用 计算退避prevBackoff * factor。
Retry如果启用,则为过滤器配置以下默认值:
-
retries: 三倍
-
series: 5XX 系列
-
methods: 获取方法
-
exceptions:IOException和TimeoutException
-
backoff: 禁用
以下清单配置了 Retry GatewayFilter:
示例 51.application.yml
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
methods: GET,POST
backoff:
firstBackoff: 10ms
maxBackoff: 50ms
factor: 2
basedOnPreviousValue: false
使用带有forward:前缀 URL 的重试过滤器时,应仔细编写目标端点,以便在发生错误时不会执行任何可能导致将响应发送到客户端并提交的操作。例如,如果目标端点是带注释的控制器,则目标控制器方法不应返回ResponseEntity错误状态代码。相反,它应该抛出Exception或发出错误信号(例如,通过Mono.error(ex)返回值),重试过滤器可以配置为通过重试来处理。
将重试过滤器与任何带有正文的 HTTP 方法一起使用时,正文将被缓存,并且网关将受到内存限制。正文缓存在由 定义的请求属性中ServerWebExchangeUtils.CACHED_REQUEST_BODY_ATTR。对象的类型是 a org.springframework.core.io.buffer.DataBuffer。
可以使用单个statusand来添加简化的“快捷方式”表示法method。
下面两个例子是等价的:
示例 52.application.yml
spring:
cloud:
gateway:
routes:
- id: retry_route
uri: https://example.org
filters:
- name: Retry
args:
retries: 3
statuses: INTERNAL_SERVER_ERROR
methods: GET
backoff:
firstBackoff: 10ms
maxBackoff: 50ms
factor: 2
basedOnPreviousValue: false
- id: retryshortcut_route
uri: https://example.org
filters:
- Retry=3,INTERNAL_SERVER_ERROR,GET,10ms,50ms,2,false
6.26. The RequestSize GatewayFilter Factory
当请求大小大于允许的限制时,RequestSize GatewayFilter工厂可以限制请求到达下游服务。过滤器接受一个maxSize参数。类型,因此maxSize is a `DataSize值可以定义为一个数字,后跟一个可选的DataUnit后缀,例如“KB”或“MB”。字节的默认值为“B”。它是以字节为单位定义的请求的允许大小限制。以下清单配置了一个RequestSize GatewayFilter:
示例 53.application.yml
spring:
cloud:
gateway:
routes:
- id: request_size_route
uri: http://localhost:8080/upload
predicates:
- Path=/upload
filters:
- name: RequestSize
args:
maxSize: 5000000
当请求因大小而被拒绝时,RequestSize GatewayFilter工厂将响应状态设置为413 Payload Too Large附加标头。errorMessage以下示例显示了这样一个errorMessage:
errorMessage` : `Request size is larger than permissible limit. Request size is 6.0 MB where permissible limit is 5.0 MB
如果未在路由定义中作为过滤器参数提供,则默认请求大小设置为 5 MB。
6.27. The SetRequestHostHeader GatewayFilter Factory
在某些情况下,可能需要覆盖主机标头。在这种情况下,SetRequestHostHeader GatewayFilter工厂可以用指定的值替换现有的主机头。过滤器接受一个host参数。以下清单配置了一个SetRequestHostHeader GatewayFilter:
示例 54.application.yml
spring:
cloud:
gateway:
routes:
- id: set_request_host_header_route
uri: http://localhost:8080/headers
predicates:
- Path=/headers
filters:
- name: SetRequestHostHeader
args:
host: example.org
工厂将主机头的SetRequestHostHeader GatewayFilter值替换为example.org。
6.28. Modify a Request Body GatewayFilter Factory
您可以使用ModifyRequestBody过滤器过滤器在网关将请求主体发送到下游之前对其进行修改。
只能使用 Java DSL 配置此过滤器。
以下清单显示了如何修改请求正文GatewayFilter:
@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;
}
}
如果请求没有正文,RewriteFilter则将通过null。Mono.empty()应返回以在请求中分配缺少的正文。
6.29. Modify a Response Body GatewayFilter Factory
您可以使用ModifyResponseBody过滤器在将响应正文发送回客户端之前对其进行修改。
只能使用 Java DSL 配置此过滤器。
以下清单显示了如何修改响应正文GatewayFilter:
@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();
}
如果响应没有正文,RewriteFilter则将通过null。Mono.empty()应返回以在响应中分配缺少的正文。
6.30. Token Relay GatewayFilter Factory
令牌中继是 OAuth2 消费者充当客户端并将传入令牌转发给传出资源请求的地方。消费者可以是纯客户端(如 SSO 应用程序)或资源服务器。
Spring Cloud Gateway 可以将 OAuth2 访问令牌向下游转发到它所代理的服务。要将此功能添加到网关,您需要添加 TokenRelayGatewayFilterFactory如下内容:
App.java
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("resource", r -> r.path("/resource")
.filters(f -> f.tokenRelay())
.uri("http://localhost:9000"))
.build();
}
或这个
application.yaml
spring:
cloud:
gateway:
routes:
- id: resource
uri: http://localhost:9000
predicates:
- Path=/resource
filters:
- TokenRelay=
并且它将(除了登录用户并获取令牌之外)将身份验证令牌传递给下游的服务(在这种情况下 /resource)。
要为 Spring Cloud Gateway 启用此功能,请添加以下依赖项
- org.springframework.boot:spring-boot-starter-oauth2-client
它是如何工作的?/src/main/java/org/springframework/cloud/gateway/security/TokenRelayGatewayFilterFactory.java[filter] 从当前经过身份验证的用户中提取访问令牌,并将其放入下游请求的请求标头中。
有关完整的工作示例,请参阅此项目。
仅当设置了将触发创建beanTokenRelayGatewayFilterFactory的适当属性时才会创建bean。 spring.security.oauth2.client.*ReactiveClientRegistrationRepository
ReactiveOAuth2AuthorizedClientServiceused by 的默认实现使用TokenRelayGatewayFilterFactory 内存数据存储。ReactiveOAuth2AuthorizedClientService 如果您需要更强大的解决方案, 您将需要提供自己的实现。
6.31. The CacheRequestBody GatewayFilter Factory
有一定的情况需要读取body。由于请求体流只能读取一次,所以我们需要缓存请求体。您可以使用CacheRequestBody过滤器在请求正文发送到下游之前缓存请求正文并从 exchagne 属性获取正文。
以下清单显示了如何缓存请求正文GatewayFilter:
@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route("cache_request_body_route", r -> r.path("/downstream/**")
.filters(f -> f.prefixPath("/httpbin")
.cacheRequestBody(String.class).uri(uri))
.build();
}
示例 55.application.yml
spring:
cloud:
gateway:
routes:
- id: cache_request_body_route
uri: lb://downstream
predicates:
- Path=/downstream/**
filters:
- name: CacheRequestBody
args:
bodyClass: java.lang.String
CacheRequestBody将提取请求正文并将其转换为正文类(例如java.lang.String,在前面的示例中定义)。然后将其放置在 中,ServerWebExchange.getAttributes()并使用 中定义的键ServerWebExchangeUtils.CACHED_REQUEST_BODY_ATTR。
此过滤器仅适用于 http 请求(包括 https)。
6.32. Default Filters
要添加过滤器并将其应用于所有路由,您可以使用spring.cloud.gateway.default-filters. 此属性采用过滤器列表。以下清单定义了一组默认过滤器:
示例 56.application.yml
spring:
cloud:
gateway:
default-filters:
- AddResponseHeader=X-Response-Default-Red, Default-Blue
- PrefixPath=/httpbin