6.GatewayFilter
工厂
路由筛选器允许以某种方式修改传入的 HTTP 请求或传出的 HTTP 响应。 路由过滤器的范围限定为特定路由。 Spring Cloud 网关包括许多内置的 GatewayFilter 工厂。
有关如何使用以下任何筛选器的更详细示例,请查看单元测试。 |
6.1. 使用AddRequestHeader
GatewayFilter
厂
这AddRequestHeader
GatewayFilter
factory 采用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
Factory 采用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
Factory 采用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
可以包含以空格分隔的 Headers 名称列表。
以下示例将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 GatewayFilter 工厂
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
在 Classpath 上。
下面的示例配置一个 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
前缀)。
主要方案是使用fallbackUri
在 Gateway 应用程序中定义内部控制器或处理程序。
但是,您也可以将请求重新路由到外部应用程序中的控制器或处理程序,如下所示:
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 网关过滤器还提供Throwable
这就是造成它的原因。
它被添加到ServerWebExchange
作为ServerWebExchangeUtils.CIRCUITBREAKER_EXECUTION_EXCEPTION_ATTR
在 Gateway 应用程序中处理回退时可以使用的属性。
对于外部控制器/处理程序方案,可以添加包含异常详细信息的标头。 你可以在FallbackHeaders GatewayFilter Factory部分找到有关执行此作的更多信息。
6.5.1. 在状态代码上使断路器跳闸
在某些情况下,您可能希望根据状态代码触发断路器
从它包装的路由返回。断路器配置对象采用
状态代码,如果返回,将导致断路器跳闸。在设置
状态代码 您希望使断路器跳闸,您可以使用带有状态代码的整数
value 或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 请求中获取。
如果 input 标头不存在,则筛选器不会产生任何影响。
如果新的命名标头已存在,则其值将使用新值进行扩充。
以下示例将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
factory 将单个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
factory 使用RateLimiter
implementation 来确定是否允许当前请求继续。如果不是,则状态为HTTP 429 - Too Many Requests
(默认情况下)。
此过滤器采用可选的keyResolver
参数和特定于 Rate Limiter 的参数(本节稍后将介绍)。
keyResolver
是一个 Bean,它实现了KeyResolver
接口。
在配置中,使用 SPEL 按名称引用 bean。#{@myKeyResolver}
是一个 SPEL 表达式,它引用名为myKeyResolver
.
下面的清单显示了KeyResolver
接口:
public interface KeyResolver {
Mono<String> resolve(ServerWebExchange exchange);
}
这KeyResolver
interface 允许可插拔策略派生用于限制请求的 key。
在未来的里程碑版本中,将有一些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.application.properties
# INVALID SHORTCUT CONFIGURATION spring.cloud.gateway.routes[0].filters[0]=RequestRateLimiter=2, 2, #{@userkeyresolver} |
6.10.1. RedisRateLimiter
Redis 实现基于 Stripe 所做的工作。
它需要使用spring-boot-starter-data-redis-reactive
Spring Boot Starters。
使用的算法是 Token Bucket Algorithm。
这redis-rate-limiter.replenishRate
property 是您希望用户每秒执行的请求数,而不丢弃任何请求。
这是填充令牌桶的速率。
这redis-rate-limiter.burstCapacity
property 是允许用户在一秒钟内执行的最大请求数。
这是令牌桶可以容纳的令牌数量。
将此值设置为 0 会阻止所有请求。
这redis-rate-limiter.requestedTokens
property 是请求花费的令牌数量。
这是每个请求从存储桶中获取的令牌数,默认为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
是一个简单的 API,它得到user
request 参数(请注意,不建议将此选项用于生产)。
您还可以将速率限制器定义为实现RateLimiter
接口。
在配置中,您可以使用 SpEL 按名称引用 Bean。#{@myRateLimiter}
是一个 SPEL 表达式,它引用一个 bean 的命名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
parameter 应为 300 系列重定向 HTTP 代码,例如 301。
这url
parameter 应为有效的 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
标头执行重定向。
6.12. 使用RemoveRequestHeader
GatewayFilter 工厂
这RemoveRequestHeader
GatewayFilter
factory 采用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
factory 采用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
factory 采用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
parameter 是请求标头允许的最大数据大小(包括 key 和 value)。这errorHeaderName
parameter 设置包含错误消息的响应标头的名称,默认情况下为 “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
Factory 采用路径regexp
parameter 和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 规范,应将其替换为 the。$
$\
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
response 标头值为object-service.prod.example.net/v2/some/object/id
被重写为api.example.com/some/object/id
.
这stripVersionMode
parameter 的可能值如下:NEVER_STRIP
,AS_IN_REQUEST
(默认)和ALWAYS_STRIP
.
-
NEVER_STRIP
:即使原始请求路径不包含版本,也不会剥离版本。 -
AS_IN_REQUEST
仅当原始请求路径不包含版本时,才会剥离版本。 -
ALWAYS_STRIP
版本始终被剥离,即使原始请求路径包含 version。
这hostValue
参数(如果提供)用于将host:port
响应部分Location
页眉。
如果未提供,则Host
request 标头。
这protocolsRegex
parameter 必须是有效的正则表达式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 规范,您必须使用 to mean。$\
$
6.19. 使用SaveSession
GatewayFilter
厂
这SaveSession
GatewayFilter
Factory 强制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
Factory 采用路径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
用给定的名称替换 (而不是添加) 所有 headers。
因此,如果下游服务器使用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用给定的名称替换(而不是添加)所有 headers。
因此,如果下游服务器使用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
.
它必须是有效的 SpringHttpStatus
.
它可能是整数值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
parameter 指示在将请求发送到下游之前要从请求中剥离的 path 中的部分数。
下面的清单配置了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
Factory 支持以下参数:
-
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
filter(如果启用):
-
retries
:三次 -
series
: 5XX 系列 -
methods
:GET 方法 -
exceptions
:IOException
和TimeoutException
-
backoff
:禁用
下面的清单配置了 RetryGatewayFilter
:
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 的前缀 URL,则应仔细编写目标端点,以便在出现错误时,它不会执行任何可能导致将响应发送到客户端并提交的作。
例如,如果目标端点是带注释的控制器,则目标控制器方法不应返回ResponseEntity 显示错误状态代码。
相反,它应该抛出一个Exception 或发出错误信号(例如,通过Mono.error(ex) return 值),重试筛选条件可以通过重试将其配置为处理。 |
当将重试过滤器与任何带有正文的 HTTP 方法一起使用时,正文将被缓存,网关将受到内存限制。正文缓存在 request 属性中,由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
type,因此可以将值定义为一个数字,后跟一个可选的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
factory 将响应状态设置为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
如果未在路由定义中作为 filter 参数提供,则默认请求大小设置为 5 MB。 |
6.28. 使用SetRequestHostHeader
GatewayFilter
厂
在某些情况下,可能需要覆盖主机标头。在这种情况下,SetRequestHostHeader
GatewayFilter
Factory 可以将现有的 Host Headers 替换为指定的 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 将 host 标头的值替换为example.org
.
6.29. 修改请求体GatewayFilter
厂
您可以使用ModifyRequestBody
filter 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. 令牌中继GatewayFilter
厂
令牌中继是 OAuth2 使用者充当客户端的地方,而 将传入令牌转发到传出资源请求。这 consumer 可以是纯 Client(如 SSO 应用程序)或 Resource 服务器。
Spring Cloud 网关可以将 OAuth2 访问令牌下游转发到服务
它是代理。要将此功能添加到网关,您需要添加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=
它会(除了登录用户和获取令牌之外)
将身份验证令牌下游传递给服务(在本例中为/resource
).
要为 Spring Cloud 网关启用此功能,请添加以下依赖项
-
org.springframework.boot:spring-boot-starter-oauth2-client
它是如何工作的?这 {githubmaster}/src/main/java/org/springframework/cloud/gateway/security/TokenRelayGatewayFilterFactory.java[过滤器] 从当前经过身份验证的用户中提取访问令牌, 并将其放入下游请求的请求标头中。
有关完整的工作示例,请参阅此项目。
一个TokenRelayGatewayFilterFactory 仅当正确的spring.security.oauth2.client.* 属性,这将触发ReactiveClientRegistrationRepository 豆。 |
的默认实现ReactiveOAuth2AuthorizedClientService 使用者TokenRelayGatewayFilterFactory 使用内存中数据存储。您需要提供自己的实施ReactiveOAuth2AuthorizedClientService 如果您需要更强大的解决方案。 |
6.32. 使用CacheRequestBody
GatewayFilter
厂
在某些情况下需要读取正文。由于请求体流只能读取一次,因此我们需要缓存请求体。
您可以使用CacheRequestBody
filter 在请求发送到下游之前缓存请求 body 并从 exchange 属性中获取 body。
下面的清单显示了如何缓存请求正文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
将提取请求正文并将其转换为 body 类(例如java.lang.String
,在前面的示例中定义)。然后将其放置在ServerWebExchange.getAttributes()
在ServerWebExchangeUtils.CACHED_REQUEST_BODY_ATTR
.
此筛选条件仅适用于 http 请求(包括 https)。 |
6.33. 使用JsonToGrpc
GatewayFilter
厂
JSONToGRPCFilter GatewayFilter Factory 将 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
Proto 定义文件。 -
service
将处理请求的服务的简称。 -
method
将处理请求的服务中的 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