6.GatewayFilter
工厂
路由过滤器允许以某种方式修改传入的 HTTP 请求或传出的 HTTP 响应。 路由过滤器的范围限定为特定路由。 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
header 添加到所有匹配请求的下游请求的标头。
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.AddResponseHeader
GatewayFilter
厂
这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-Red:Blue
header 添加到所有匹配请求的下游响应标头。
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.DedupeResponseHeader
GatewayFilter
厂
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
这将删除Access-Control-Allow-Credentials
和Access-Control-Allow-Origin
响应标头,以防网关 CORS 逻辑和下游逻辑都添加它们。
这DedupeResponseHeader
filter 还接受可选的strategy
参数。
接受的值是RETAIN_FIRST
(默认),RETAIN_LAST
和RETAIN_UNIQUE
.
6.5. Spring Cloud CircuitBreaker 网关过滤器工厂
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 CircuitBreakerGatewayFilter
:
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
以下列表在 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
在网关应用程序中定义内部控制器或处理程序。
但是,您也可以将请求重新路由到外部应用程序中的控制器或处理程序,如下所示:
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
endpoint 或处理程序。但是,另一个应用程序中有一个,在localhost:9994
.
如果请求被转发到回退,Spring Cloud CircuitBreaker Gateway 过滤器还提供Throwable
这导致了它。它被添加到ServerWebExchange
作为ServerWebExchangeUtils.CIRCUITBREAKER_EXECUTION_EXCEPTION_ATTR
在网关应用程序中处理回退时可以使用的属性。
对于外部控制器/处理程序方案,可以添加带有异常详细信息的标头。可以在 FallbackHeaders GatewayFilter 工厂部分找到有关执行此作的详细信息。
6.5.1. 在状态代码上跳闸断路器
在某些情况下,您可能希望根据状态代码跳闸断路器从它包装的路由返回。断路器配置对象采用状态代码列表,如果返回该状态代码将导致断路器跳闸。设置状态代码,您想要跳闸断路器,您可以使用状态代码为值或字符串表示形式的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
factory 允许您在转发给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
filters:
- name: FallbackHeaders
args:
executionExceptionTypeHeaderName: Test-Header
在此示例中,在运行熔断器时发生执行异常后,请求将转发到fallback
运行在localhost:9994
.
具有异常类型、消息和(如果可用)根本原因异常类型和消息的标头将通过FallbackHeaders
Filter。
您可以通过设置以下参数的值(以其默认值显示)来覆盖配置中标头的名称:
-
executionExceptionTypeHeaderName
("Execution-Exception-Type"
) -
executionExceptionMessageHeaderName
("Execution-Exception-Message"
) -
rootCauseExceptionTypeHeaderName
("Root-Cause-Exception-Type"
) -
rootCauseExceptionMessageHeaderName
("Root-Cause-Exception-Message"
)
有关断路器和网关的更多信息,请参阅 Spring Cloud CircuitBreaker Factory 部分。
6.7.MapRequestHeader
GatewayFilter
厂
这MapRequestHeader
GatewayFilter
工厂采取fromHeader
和toHeader
参数。
它创建一个新的命名标头 (toHeader
),并且从现有的命名标头 (fromHeader
) 来自传入的 HTTP 请求。
如果输入标头不存在,则筛选器没有影响。
如果新的命名标头已存在,则其值将使用新值进行扩充。
以下示例配置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
factory 没有参数。
此筛选器设置路由筛选器检查的请求属性,以确定是否应发送原始主机标头,而不是由 HTTP 客户端确定的主机标头。
以下示例配置PreserveHostHeader
GatewayFilter
:
spring:
cloud:
gateway:
routes:
- id: preserve_host_route
uri: https://example.org
filters:
- PreserveHostHeader
6.10.RequestRateLimiter
GatewayFilter
厂
这RequestRateLimiter
GatewayFilter
工厂使用RateLimiter
实现以确定是否允许当前请求继续。如果不是,则状态为HTTP 429 - Too Many Requests
(默认情况下)返回。
此过滤器采用可选的keyResolver
参数和特定于速率限制器的参数(本节稍后将介绍)。
keyResolver
是一个实现KeyResolver
接口。
在配置中,使用 SpEL 按名称引用 bean。#{@myKeyResolver}
是一个 SpEL 表达式,它引用名为myKeyResolver
.
以下列表显示了KeyResolver
接口:
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
性能。
这 实施例 32.应用程序属性
# 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
到以秒为单位的时间跨度,以及burstCapacity
到产品replenishRate
和requestedTokens
,例如设置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
request 参数(请注意,不建议在生产环境中使用)。
您还可以将速率限制器定义为实现RateLimiter
接口。
在配置中,您可以使用 SpEL 按名称引用 bean。#{@myRateLimiter}
是一个 SpEL 表达式,它引用名为myRateLimiter
.
以下列表定义了一个速率限制器,该限制器使用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
厂
这RedirectTo
GatewayFilter
factory 采用两个参数,status
和url
. 这status
参数应该是 300 系列重定向的 HTTP 代码,例如 301。
这url
参数应该是一个有效的网址。
这是Location
页眉。
对于相对重定向,您应该使用uri: no://op
作为路由定义的 URI。
以下列表配置了一个RedirectTo
GatewayFilter
:
spring:
cloud:
gateway:
routes:
- id: prefixpath_route
uri: https://example.org
filters:
- RedirectTo=302, https://acme.org
这将发送一个状态 302,其中包含Location:https://acme.org
header 来执行重定向。
6.12.RemoveRequestHeader
GatewayFilter 工厂
这RemoveRequestHeader
GatewayFilter
工厂采用name
参数。
它是要删除的标头的名称。
以下列表配置了一个RemoveRequestHeader
GatewayFilter
:
spring:
cloud:
gateway:
routes:
- id: removerequestheader_route
uri: https://example.org
filters:
- RemoveRequestHeader=X-Request-Foo
这会删除X-Request-Foo
标头。
6.13.RemoveResponseHeader
GatewayFilter
厂
这RemoveResponseHeader
GatewayFilter
工厂采用name
参数。
它是要删除的标头的名称。
以下列表配置了一个RemoveResponseHeader
GatewayFilter
:
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.RemoveRequestParameter
GatewayFilter
厂
这RemoveRequestParameter
GatewayFilter
工厂采用name
参数。
它是要删除的查询参数的名称。
以下示例配置RemoveRequestParameter
GatewayFilter
:
spring:
cloud:
gateway:
routes:
- id: removerequestparameter_route
uri: https://example.org
filters:
- RemoveRequestParameter=red
这将删除red
参数。
6.15.RequestHeaderSize
GatewayFilter
厂
这RequestHeaderSize
GatewayFilter
工厂采取maxSize
和errorHeaderName
参数。
这maxSize
参数是请求标头允许的最大数据大小(包括键和值)。这errorHeaderName
参数设置包含错误消息的响应标头的名称,默认为“errorMessage”。
以下列表配置了一个RequestHeaderSize
GatewayFilter
:
spring:
cloud:
gateway:
routes:
- id: requestheadersize_route
uri: https://example.org
filters:
- RequestHeaderSize=1000B
如果任何请求标头的大小大于 1000 字节,这将发送状态 431。
6.16.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.17.RewriteLocationResponseHeader
GatewayFilter
厂
这RewriteLocationResponseHeader
GatewayFilter
factory 修改Location
response 标头,通常是为了摆脱特定于后端的细节。
这需要stripVersionMode
,locationHeaderName
,hostValue
和protocolsRegex
参数。
以下列表配置了一个RewriteLocationResponseHeader
GatewayFilter
:
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.18.RewriteResponseHeader
GatewayFilter
厂
这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.19.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.20.SecureHeaders
GatewayFilter
厂
这SecureHeaders
GatewayFilter
factory 根据本博客文章中的建议,向响应添加了许多标头。
将添加以下标头(以其默认值显示):
-
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
Namespace。
以下属性可用:
-
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.21.SetPath
GatewayFilter
厂
这SetPath
GatewayFilter
工厂走一条路径template
参数。
它提供了一种通过允许路径的模板化段来作请求路径的简单方法。
这使用了 Spring Framework 中的 URI 模板。
允许多个匹配的段。
以下示例配置SetPath
GatewayFilter
:
spring:
cloud:
gateway:
routes:
- id: setpath_route
uri: https://example.org
predicates:
- Path=/red/{segment}
filters:
- SetPath=/{segment}
对于请求路径/red/blue
,这会将路径设置为/blue
在发出下游请求之前。
6.22.SetRequestHeader
GatewayFilter
厂
这SetRequestHeader
GatewayFilter
工厂采取name
和value
参数。
以下列表配置了一个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.23.SetResponseHeader
GatewayFilter
厂
这SetResponseHeader
GatewayFilter
工厂采取name
和value
参数。
以下列表配置了一个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 变量可以在值中使用,并将在运行时扩展。
以下示例配置了SetResponseHeader
GatewayFilter
使用变量:
spring:
cloud:
gateway:
routes:
- id: setresponseheader_route
uri: https://example.org
predicates:
- Host: {segment}.myhost.org
filters:
- SetResponseHeader=foo, bar-{segment}
6.24.SetStatus
GatewayFilter
厂
这SetStatus
GatewayFilter
factory 采用单个参数,status
.
它必须是有效的弹簧HttpStatus
.
它可以是整数值404
或枚举的字符串表示形式:NOT_FOUND
.
以下列表配置了一个SetStatus
GatewayFilter
:
spring:
cloud:
gateway:
routes:
- id: setstatusstring_route
uri: https://example.org
filters:
- SetStatus=UNAUTHORIZED
- id: setstatusint_route
uri: https://example.org
filters:
- SetStatus=401
无论哪种情况,响应的 HTTP 状态都设置为 401。
您可以配置SetStatus
GatewayFilter
在响应的标头中返回代理请求的原始 HTTP 状态代码。
如果配置了以下属性,则标头将添加到响应中:
spring:
cloud:
gateway:
set-status:
original-status-header-name: original-http-status
6.25.StripPrefix
GatewayFilter
厂
这StripPrefix
GatewayFilter
factory 采用一个参数,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.26. 重试GatewayFilter
厂
这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
为 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,则应仔细编写目标端点,以便在发生错误时,它不会执行任何可能导致响应发送到客户端并提交的作。
例如,如果目标终结点是带批注的控制器,则目标控制器方法不应返回ResponseEntity 带有错误状态代码。
相反,它应该抛出一个Exception 或发出错误信号(例如,通过Mono.error(ex) 返回值),重试筛选器可以通过重试来配置为处理。 |
将重试筛选器与任何具有正文的 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.27.RequestSize
GatewayFilter
厂
当请求大小大于允许的限制时,RequestSize
GatewayFilter
factory 可以限制请求到达下游服务。
过滤器采用maxSize
参数。
这maxSize
是一个DataSize
类型,因此可以将值定义为数字后跟可选的DataUnit
后缀,例如“KB”或“MB”。字节的默认值为“B”。
它是以字节为单位定义的请求的允许大小限制。
以下列表配置了一个RequestSize
GatewayFilter
:
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.28.SetRequestHostHeader
GatewayFilter
厂
在某些情况下,可能需要覆盖主机标头。在这种情况下,SetRequestHostHeader
GatewayFilter
factory 可以将现有主机标头替换为指定的 VAUE。过滤器采用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
这SetRequestHostHeader
GatewayFilter
factory 将主机标头的值替换为example.org
.
6.29. 修改请求正文GatewayFilter
厂
您可以使用ModifyRequestBody
filter filter 以在网关向下游发送请求正文之前修改请求正文。
只能使用 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.30. 修改响应正文GatewayFilter
厂
您可以使用ModifyResponseBody
filter 以在将响应正文发送回客户端之前对其进行修改。
只能使用 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.31. Tokens中继GatewayFilter
厂
Tokens中继是 OAuth2 消费者充当客户端和将传入Tokens转发给传出资源请求的地方。 这 consumer 可以是纯客户端(如 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
它是如何工作的? 这 {githubmaster}/src/main/java/org/springframework/cloud/gateway/security/TokenRelayGatewayFilterFactory.java[过滤器]从当前经过身份验证的用户中提取访问Tokens,并将其放在下游请求的请求头中。
有关完整的工作示例,请参阅此项目。
一个TokenRelayGatewayFilterFactory 只有当适当的spring.security.oauth2.client.* 设置属性,这将触发创建ReactiveClientRegistrationRepository 豆。 |
默认实现ReactiveOAuth2AuthorizedClientService 使用者TokenRelayGatewayFilterFactory 使用内存中数据存储。您需要提供自己的实现ReactiveOAuth2AuthorizedClientService 如果您需要更强大的解决方案。 |
6.32.CacheRequestBody
GatewayFilter
厂
在某些情况下需要读取正文。由于请求正文流只能读取一次,因此我们需要缓存请求正文。您可以使用CacheRequestBody
filter 以缓存请求正文,然后再将其发送到下游,并从 Exchange 属性获取正文。
以下列表显示了如何缓存请求正文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();
}
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.33.JsonToGrpc
GatewayFilter
厂
JSONToGRPCFilter GatewayFilter 工厂将 JSON 有效负载转换为 gRPC 请求。
筛选器采用以下参数:
-
protoDescriptor
Proto 描述符文件。
可以使用protoc
指定--descriptor_set_out
旗:
protoc --proto_path=src/main/resources/proto/ \
--descriptor_set_out=src/main/resources/proto/hello.pb \
src/main/resources/proto/hello.proto
-
protoFile
原型定义文件。 -
service
将处理请求的服务的简称。 -
method
将处理请求的服务中的方法名称。
streaming 不支持。 |
application.yml。
@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route("json-grpc", r -> r.path("/json/hello").filters(f -> {
String protoDescriptor = "file:src/main/proto/hello.pb";
String protoFile = "file:src/main/proto/hello.proto";
String service = "HelloService";
String method = "hello";
return f.jsonToGRPC(protoDescriptor, protoFile, service, method);
}).uri(uri))
spring:
cloud:
gateway:
routes:
- id: json-grpc
uri: https://localhost:6565/testhello
predicates:
- Path=/json/**
filters:
- name: JsonToGrpc
args:
protoDescriptor: file:proto/hello.pb
protoFile: file:proto/hello.proto
service: HelloService
method: hello
当通过网关发出请求时/json/hello
请求将使用hello.proto
,发送到HelloService/hello
,并将响应转换回 JSON。
默认情况下,它将创建一个NettyChannel
使用默认的TrustManagerFactory
. 然而,这个TrustManager
可以通过创建类型GrpcSslConfigurer
:
@Configuration
public class GRPCLocalConfiguration {
@Bean
public GRPCSSLContext sslContext() {
TrustManager trustManager = trustAllCerts();
return new GRPCSSLContext(trustManager);
}
}
6.34. 默认过滤器
要添加过滤器并将其应用于所有路由,您可以使用spring.cloud.gateway.default-filters
. 此属性采用筛选器列表。以下列表定义了一组默认筛选器:
spring:
cloud:
gateway:
default-filters:
- AddResponseHeader=X-Response-Default-Red, Default-Blue
- PrefixPath=/httpbin