6. GatewayFilter 工厂
路由过滤器允许以某种方式修改传入的 HTTP 请求或传出的 HTTP 响应。</p><p>路由过滤器作用于特定的路由范围之内。</p><p>Spring Cloud Gateway 包含许多内置的 GatewayFilter 工厂。
| 有关如何使用以下任一过滤器的更详细示例,请查看单元测试。 |
6.1. AddRequestHeader GatewayFilter 工厂
该 AddRequestHeader GatewayFilter 工厂接受一个 name 和 value 参数。
以下示例配置了一个 AddRequestHeader GatewayFilter:
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,它使用一个变量:
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 GatewayFilter 工厂接受一个 name 和 value 参数。
以下示例配置了一个 AddRequestParameter GatewayFilter:
spring:
cloud:
gateway:
routes:
- id: add_request_parameter_route
uri: https://example.org
filters:
- AddRequestParameter=red, blue
这将在所有匹配的请求中,将red=blue添加到下游请求的查询字符串中。
AddRequestParameter 可知用于匹配路径或主机的 URI 变量。
URI 变量可在值中使用,并在运行时进行扩展。
以下示例配置了一个 AddRequestParameter GatewayFilter,它使用一个变量:
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 GatewayFilter 工厂接受一个 name 和 value 参数。
以下示例配置了一个 AddResponseHeader GatewayFilter:
spring:
cloud:
gateway:
routes:
- id: add_response_header_route
uri: https://example.org
filters:
- AddResponseHeader=X-Response-Red, Blue
这会向所有匹配请求的下游响应头中添加 X-Response-Foo:Bar 个标头。
AddResponseHeader是意识到用于匹配路径或主机的URI变量。
URI变量可用于值并将在运行时进行扩展。
下面的例子配置了一个AddResponseHeader GatewayFilter,它使用一个变量:
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 的 0 1 工厂
DedupeResponseHeader GatewayFilter 工厂需要一个 name 参数和一个可选的 strategy 参数。 name 可以包含一个空格分隔的标头名称列表。 以下示例配置了一个 DedupeResponseHeader GatewayFilter:
spring:
cloud:
gateway:
routes:
- id: dedupe_response_header_route
uri: https://example.org
filters:
- DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin
This removes duplicate values of Access-Control-Allow-Credentials and Access-Control-Allow-Origin response headers in cases when both the gateway CORS logic and the downstream logic add them.
DedupeResponseHeader 过滤器还接受一个可选的 strategy 参数。默认值为 RETAIN_FIRST,其他值有 RETAIN_LAST 和 RETAIN_UNIQUE。
6.5. Spring Cloud CircuitBreaker GatewayFilter Factory
Spring Cloud CircuitBreaker GatewayFilter工厂使用Spring Cloud CircuitBreaker API包装Gateway路线 在一个断路器中。 Spring Cloud CircuitBreaker支持可以与Spring Cloud Gateway一起使用的多个库。 Spring Cloud默认支持Resilience4J。
要启用SpringCloudCircuitBreaker筛选器,你需要将spring-cloud-starter-circuitbreaker-reactor-resilience4j放在类路径上。
下面的例子配置了一个SpringCloudCircuitBreakerGatewayFilter:
spring:
cloud:
gateway:
routes:
- id: circuitbreaker_route
uri: https://example.org
filters:
- CircuitBreaker=myCircuitBreaker
要配置断路器,请参阅您使用的底层断路器实现的配置。
Spring Cloud CircuitBreaker筛选器还可以接受可选的fallbackUri参数。
目前,仅支持forward:格式的URI。
如果调用了回退,请求将转发到与URI匹配的控制器。
下面的示例配置了这样的回退:
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
The following listing does the same thing in 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();
}
此示例在回退电路断路器时转发到/inCaseofFailureUseThisURI。请注意,此示例还演示了(可选)Spring Cloud LoadBalancer负载平衡(由目标URI前缀lb定义)。
Spring 框架的开发主要场景是使用 fallbackUri 来在网关应用程序中定义内部控制器或处理程序。
然而,您也可以将请求重定向到外部应用程序中的控制器或处理程序,如下所示:
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电路板开路网关过滤器还提供0 这导致它。它添加到1 作为2 属性可用于在网关应用程序中处理降级。)
(外接控制器/处理程序方案中,可以添加标题包含异常详细信息。您可以在
6.5.1. 基于状态码中断电路
在某些情况下,您可能需要根据包装路线返回的状态代码来触发电路断路器。电路断路器配置对象接受一个列表状态码如果返回这些状态码将导致电路断路器被触发。设置要触发的时
当设置要触发的电路断路器的状态代码时,您可以使用整数,其中包含状态代码值或String表示HttpStatus枚举。
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"
@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. FallbackHeaders GatewayFilter 工厂
FallbackHeaders GatewayFilter 工厂The FallbackHeaders 工厂让你能够在转发到外部应用程序中的 fallbackUri 时,在请求头中添加 Spring Cloud CircuitBreaker 执行异常的详细信息,如下情境所示:
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
在本例中,运行熔断器时发生执行异常后,在运行在localhost:9994上的应用程序中,请求将转发到fallback端点或处理程序。由FallbackHeaders过滤器添加带有异常类型、消息和(如果可用)根原因异常类型和消息的标头到该请求。
您可以通过设置以下参数的值(显示为默认值)来覆盖配置中的标题名称:<br>
-
executionExceptionTypeHeaderName("Execution-Exception-Type") -
executionExceptionMessageHeaderName("Execution-Exception-Message") -
rootCauseExceptionTypeHeaderName("Root-Cause-Exception-Type") -
rootCauseExceptionMessageHeaderName("Root-Cause-Exception-Message")
有关断路器和网关的更多信息,请参阅Spring Cloud 断路器工厂部分。
6.7. MapRequestHeader GatewayFilter 工厂
该MapRequestHeaderGatewayFilter工厂接受fromHeader和toHeader参数。它创建一个新的命名标头(toHeader),并且值是从传入的HTTP请求中的现有命名标头(fromHeader)中提取出来的。如果输入标头不存在,则过滤器不起作用。如果新命名标头已存在,则其值将与新的值合并。MapRequestHeader的配置如下所示:
spring:
cloud:
gateway:
routes:
- id: map_request_header_route
uri: https://example.org
filters:
- MapRequestHeader=Blue, X-Request-Red
这会向下游请求添加 X-Request-Red:<values> 头部,并使用传入的 HTTP 请求Blue 头部中的更新值。
6.8. PrefixPath GatewayFilter 工厂
该 PrefixPath GatewayFilter 工厂接受一个单个的 prefix 参数。
以下示例配置了 PrefixPath GatewayFilter:
spring:
cloud:
gateway:
routes:
- id: prefixpath_route
uri: https://example.org
filters:
- PrefixPath=/mypath
这将把 /mypath 前缀添加到所有匹配请求的路径中。因此,对 /hello 的请求将被发送到 /mypath/hello。
6.9. PreserveHostHeader GatewayFilter 工厂
工厂 PreserveHostHeader GatewayFilter 没有参数。
此过滤器设置一个请求属性,路由过滤器检查该属性以确定是否应发送原始主机标头,而不是由 HTTP 客户端确定的主机标头。
以下示例配置了 PreserveHostHeader GatewayFilter:
spring:
cloud:
gateway:
routes:
- id: preserve_host_route
uri: https://example.org
filters:
- PreserveHostHeader
6.10. RequestRateLimiter GatewayFilter 工厂
该RequestRateLimiterGatewayFilter工厂使用RateLimiter实现来确定当前请求是否允许继续。如果否,则返回状态HTTP 429 - Too Many Requests(默认情况下)。
此过滤器采用一个可选的keyResolver参数以及速率限制器特定的参数(在本节后面描述)。
keyResolver 是一个实现了 KeyResolver 接口的 Bean。
在配置中,使用 SpEL 表达式通过名称引用该 Bean。#{@myKeyResolver} 是一个引用名为 myKeyResolver 的 Bean 的 SpEL 表达式。
下面列出的是 KeyResolver 接口:
public interface KeyResolver {
Mono<String> resolve(ServerWebExchange exchange);
}
该KeyResolver接口使可插入的策略能够推导出限制请求的密钥。在未来的里程碑版本中,将有一些KeyResolver实现。
默认实现为KeyResolver的是PrincipalNameKeyResolver,它从ServerWebExchange获取Principal并调用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属性可以调整此行为。
|
快捷方式符号不能配置 示例31. application.properties
# INVALID SHORTCUT CONFIGURATION
spring.cloud.gateway.routes[0].filters[0]=RequestRateLimiter=2, 2, #{@userkeyresolver}
|
6.10.1. Redis RateLimiter
Redis 的实现基于在 Stripe 完成的工作。它需要使用 spring-boot-starter-data-redis-reactive Spring Boot Starters。
使用的算法是Tokens桶算法。
该redis-rate-limiter.replenishRate属性是您希望用户每秒允许执行的请求数,而不会有任何请求被丢弃。这是Tokens桶填充的速率。
属性redis-rate-limiter.burstCapacity表示用户在单秒内允许执行的最大请求数。
这是Tokens桶可以容纳的Tokens数。
将此值设置为零会阻止所有请求。
该redis-rate-limiter.requestedTokens属性是请求所需的Tokens数量。每个请求从桶中取出的Tokens数,默认为1。
通过在replenishRate和burstCapacity中设置相同的值来实现稳定的速率。
通过将burstCapacity设置得高于replenishRate,可以允许临时突发情况。
在这种情况下,在突发之间需要给速率限制器一些时间(根据replenishRate),因为连续两次突发会导致请求被丢弃(HTTP 429 - Too Many Requests)。
下面的列表配置了一个redis-rate-limiter:
低于 1 request/s 的限制是通过将 replenishRate 设置为所需的请求数量,requestedTokens 设置为时间范围(秒),以及将 replenishRate 和 requestedTokens 相乘后得到的结果设置到 burstCapacity 来实现的。例如,若设置了 replenishRate=1、requestedTokens=60 和 burstCapacity=60,则会导致每 1 request/min 秒内只能有指定数量的请求。
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:
@Bean
KeyResolver userKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));
}
这定义了每个用户的请求速率限制为每秒10次。允许突发20次请求,但在下一秒内只有10次请求可用。
代码KeyResolver是一个简单的获取user请求参数的示例(请注意,不建议在生产环境中使用)。
你也可以将速率限制器定义为实现RateLimiter接口的bean。在配置中,你可以使用SpEL通过名称引用该bean。#{@myRateLimiter}是引用名为myRateLimiter的bean的SpEL表达式。下面的列表定义了一个速率限制器,它使用了前一个列表中定义的KeyResolver:
spring:
cloud:
gateway:
routes:
- id: requestratelimiter_route
uri: https://example.org
filters:
- name: RequestRateLimiter
args:
rate-limiter: "#{@myRateLimiter}"
key-resolver: "#{@userKeyResolver}"
6.11. RedirectTo GatewayFilter 工厂
工厂RedirectToGatewayFilter需要两个参数,status和url。
参数status应为300系列重定向HTTP代码,例如301。
参数url应为有效URL。
这是Location标头的值。
对于相对重定向,请在路由定义中使用uri: no://op作为uri。
以下清单配置了RedirectToGatewayFilter:
spring:
cloud:
gateway:
routes:
- id: prefixpath_route
uri: https://example.org
filters:
- RedirectTo=302, https://acme.org
这将发送一个状态为 302 的响应,并带有Location:https://acme.org头信息,以执行重定向。
6.12. RemoveRequestHeader 网关过滤器工厂
该RemoveRequestHeaderGatewayFilter工厂接受一个name参数。它是要删除的头部名称。RemoveRequestHeaderGatewayFilter配置如下所示:
spring:
cloud:
gateway:
routes:
- id: removerequestheader_route
uri: https://example.org
filters:
- RemoveRequestHeader=X-Request-Foo
在将标头发送到下游之前,将其删除X-Request-Foo。
6.13. RemoveResponseHeader GatewayFilter 工厂
该RemoveResponseHeaderGatewayFilter工厂接受一个name参数。它是要删除的头部名称。RemoveResponseHeaderGatewayFilter配置如下所示:
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.RemoveRequestParameterGatewayFilter工厂
该RemoveRequestParameterGatewayFilter工厂接受一个name参数。它是要删除的查询参数的名称。以下示例配置了RemoveRequestParameterGatewayFilter:
spring:
cloud:
gateway:
routes:
- id: removerequestparameter_route
uri: https://example.org
filters:
- RemoveRequestParameter=red
这将在参数发送到下游之前将其移除。red
6.15. RewritePath GatewayFilter 工厂
该 RewritePath GatewayFilter 工厂接受一个路径 regexp 参数和一个 replacement 参数。此功能使用 Java 正则表达式提供了一种灵活的方式来重写请求路径。以下列表配置了 RewritePath GatewayFilter:
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 工厂
工厂RewriteLocationResponseHeaderGatewayFilter修改响应头Location的值,通常是为了消除后端特定细节。
它需要stripVersionMode、locationHeaderName、hostValue和protocolsRegex参数。
下面的列表配置了RewriteLocationResponseHeaderGatewayFilter:
spring:
cloud:
gateway:
routes:
- id: rewritelocationresponseheader_route
uri: http://example.org
filters:
- RewriteLocationResponseHeader=AS_IN_REQUEST, Location, ,
例如,对于请求POST api.example.com/some/object/name,响应头值Location为object-service.prod.example.net/v2/some/object/id被重写为api.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. Factory
该 RewriteResponseHeader GatewayFilter 工厂接受 name、regexp 和 replacement 参数。
它使用 Java 正则表达式以灵活的方式重写响应头值。
以下示例配置了 RewriteResponseHeader GatewayFilter:
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 的情况,在发出下游请求后将其设置为 /42?user=ford&password=***&flag=true。
由于YAML规范,您必须使用 $\ 来表示 $。
6.18. SaveSession GatewayFilter 工厂
该 SaveSession GatewayFilter 工厂在将调用转发到下游之前强制执行 WebSession::save 操作。在此之前,当使用类似 Spring Session 的延迟数据存储时特别有用,并且您需要确保在进行转发调用之前已保存会话状态。下面的示例配置了 SaveSession GatewayFilter:
spring:
cloud:
gateway:
routes:
- id: save_session
uri: https://example.org
predicates:
- Path=/foo/**
filters:
- SaveSession
如果您将Spring Security与Spring Session集成,并希望确保安全详细信息已转发到远程进程,则这一点至关重要。
6.19. SecureHeaders GatewayFilter 工厂
该SecureHeadersGatewayFilter工厂按照此博客文章中的建议,向响应中添加了许多标头。
添加了以下标头(显示其默认值):
-
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. SetPath GatewayFilter 工厂
The SetPath GatewayFilter factory takes a path template parameter.
It offers a simple way to manipulate the request path by allowing templated segments of the path. This uses the URI templates from Spring Framework. Multiple matching segments are allowed.
The following example configures a SetPath GatewayFilter:
spring:
cloud:
gateway:
routes:
- id: setpath_route
uri: https://example.org
predicates:
- Path=/red/{segment}
filters:
- SetPath=/{segment}
对于请求路径/red/blue,此操作会在发出下游请求之前将路径设置为/blue。
6.21. SetRequestHeader GatewayFilter 工厂
The SetRequestHeader GatewayFilter 工厂需要 name 和 value 参数。
The following listing configures a SetRequestHeader GatewayFilter:
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,它使用一个变量:
spring:
cloud:
gateway:
routes:
- id: setrequestheader_route
uri: https://example.org
predicates:
- Host: {segment}.myhost.org
filters:
- SetRequestHeader=foo, bar-{segment}
6.22. SetResponseHeader GatewayFilter 工厂
The SetResponseHeader GatewayFilter 工厂需要 name 和 value 参数。
The following listing configures a SetResponseHeader GatewayFilter:
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变量可以在值中使用,并在运行时展开。
以下示例配置了一个SetResponseHeaderGatewayFilter,该配置使用了变量:
spring:
cloud:
gateway:
routes:
- id: setresponseheader_route
uri: https://example.org
predicates:
- Host: {segment}.myhost.org
filters:
- SetResponseHeader=foo, bar-{segment}
6.23. SetStatus GatewayFilter 工厂
工厂SetStatus GatewayFilter接受一个参数,status。它必须是一个有效的Spring HttpStatus。404可以是整数值或者枚举的字符串表示形式:NOT_FOUND。下面的清单配置了一个SetStatus GatewayFilter:
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。
您可以配置SetStatusGatewayFilter,以便将代理请求中的原始HTTP状态码返回到响应的标头中。如果使用以下属性进行配置,则会向响应添加该标头:
spring:
cloud:
gateway:
set-status:
original-status-header-name: original-http-status
6.24. StripPrefix GatewayFilter 工厂
工厂需要一个参数StripPrefix,GatewayFilter。参数parts表示在将请求发送到下游之前要从路径中剥离的部分数量。parts指定此值。以下列表配置了一个StripPrefix GatewayFilter:
spring:
cloud:
gateway:
routes:
- id: nameRoot
uri: https://nameservice
predicates:
- Path=/name/**
filters:
- StripPrefix=2
当通过网关向 /name/blue/red 发出请求时,发送到 nameservice 的请求看起来像 nameservice/red。
6.25. 重试GatewayFilter工厂
该RetryGatewayFilter工厂支持以下参数:
-
retries: 应该尝试的重试次数。 -
statuses: 应该重试的HTTP状态码,使用org.springframework.http.HttpStatus表示。 -
methods: 应该重试的 HTTP 方法,使用org.springframework.http.HttpMethod表示。 -
series: 表示要重试的状态码系列,使用org.springframework.http.HttpStatus.Series。 -
exceptions: 应该重试的抛出异常列表。 -
backoff: 配置的指数退避重试机制。 重试将在一个退避间隔后进行,其中firstBackoff * (factor ^ n)是迭代次数。 如果配置了maxBackoff,则最大应用的退避时间为maxBackoff。 如果basedOnPreviousValue为 true,则使用prevBackoff * factor来计算退避时间。
如果启用,以下默认值已为 Retry 过滤器配置:
-
retries: 三次 -
series: 5XX系列 -
methods: GET 方法 -
exceptions:IOException和TimeoutException -
backoff: 已禁用
以下列表配置了重试GatewayFilter:
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的重试过滤器时,应仔细编写目标端点,以便在发生错误时不执行任何可能导致向客户端发送响应并提交的操作。例如,如果目标端点是一个注解控制器,则目标控制器方法不应返回 相反,它应该抛出 |
使用重试过滤器与任何带有正文的 HTTP 方法时,正文将被缓存且网关将变得内存受限。正文被缓存在一个由 ServerWebExchangeUtils.CACHED_REQUEST_BODY_ATTR 定义的请求属性中。该对象的类型是 org.springframework.core.io.buffer.DataBuffer。 |
可以通过添加单个status和method来简化“快捷方式”符号。
以下两个示例是等效的:
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. RequestSize GatewayFilter 工厂
当请求大小超过允许的限制时,RequestSizeGatewayFilter工厂可以阻止请求到达下游服务。
该过滤器需要一个maxSize参数。maxSize is a `DataSize类型,因此值可以定义为数字后跟可选的DataUnit后缀,如“KB”或“MB”。默认为'B'表示字节。
这是以字节为单位定义的请求的允许大小限制。
以下列表配置了RequestSizeGatewayFilter:
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
| 如果在路由定义中未作为过滤器参数提供,则默认请求大小设置为五兆字节。 |
6.27. SetRequestHostHeader GatewayFilter 工厂
在某些情况下,可能需要覆盖主机标头。在这种情况下,SetRequestHostHeader GatewayFilter 工厂可以将现有的主机标头替换为指定值。
该过滤器接受一个host参数。
以下列表配置了SetRequestHostHeader GatewayFilter:
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
代码SetRequestHostHeaderGatewayFilter工厂用example.org替换主机标头的值。
6.28. 修改请求正文 GatewayFilter 工厂
您可以使用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. 修改响应正文GatewayFilter 工厂
您可以使用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 继电器 GatewayFilter 工厂
Tokens中继是指一个OAuth2消费者充当客户端,并将传入的Tokens转发到传出的资源请求。该消费者可以是纯客户端(如SSO应用程序)或资源服务器。
Spring Cloud Gateway 可以将 OAuth2 访问Tokens转发到它代理的下游服务。要向网关添加此功能,您需要像这样添加TokenRelayGatewayFilterFactory:
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("resource", r -> r.path("/resource")
.filters(f -> f.tokenRelay())
.uri("http://localhost:9000"))
.build();
}
或者这个
spring:
cloud:
gateway:
routes:
- id: resource
uri: http://localhost:9000
predicates:
- Path=/resource
filters:
- TokenRelay=
并且它会(除记录用户登录并获取Tokens外)
将身份验证Tokens传递给下游服务(在这种情况下
/resource)。
要为 Spring Cloud Gateway 启用此功能,请添加以下依赖项
-
org.springframework.boot:spring-boot-starter-oauth2-client
它是如何工作的?该<code>{githubmaster}/src/main/java/org/springframework/cloud/gateway/security/TokenRelayGatewayFilterFactory.java</code>过滤器从当前经过身份验证的用户中提取访问Tokens,并将其放入请求头中,供下游请求使用。
有关完整的工作示例,请参阅此项目。
一个 TokenRelayGatewayFilterFactory 的 bean 只有在设置了适当的 spring.security.oauth2.client.* 属性时才会被创建,这将触发 ReactiveClientRegistrationRepository bean 的创建。 |
ReactiveOAuth2AuthorizedClientService 的默认实现由 TokenRelayGatewayFilterFactory
使用内存中的数据存储。如果您需要更强大的解决方案,
则必须提供自己的实现 ReactiveOAuth2AuthorizedClientService。 |
6.31. 默认过滤器
要添加一个过滤器并将其应用于所有路由,可以使用spring.cloud.gateway.default-filters。此属性接受一个过滤器列表。以下清单定义了一组默认过滤器:
spring:
cloud:
gateway:
default-filters:
- AddResponseHeader=X-Response-Default-Red, Default-Blue
- PrefixPath=/httpbin