一 路由过滤器(GatewayFilter)
路由过滤器允许以某种方式修改传入的HTTP请求或传出的HTTP响应。路由过滤器主要是作用于特定路由。 Spring Cloud Gateway包括许多内置的GatewayFilter工厂,每一个工厂都是一个路由过滤器。
二框架已实现的路由过滤器
要自定义路由过滤器,我们更多的会去参考gateway已帮我定义好的一些过滤器,了解其中的原理和实现方式,如果官方定义的无法满足我们的要求,我们才会考虑去自定义。
AddRequestHeader
GatewayFilter
Factory增加请求头的路由过滤器,主要接收
name
和value
两个参数,用法参考以下官网示例:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17spring:
cloud:
gateway:
routes:
- id: add_request_header_route
uri: https://example.org
filters:
# 增加请求头 X-Request-red:blue
- AddRequestHeader=X-Request-red, blue
- id: add_request_header_route2
uri: https://example.org
predicates:
- Path=/red/{segment}
filters:
# 增加请求头 url变量可以在value中引用 如下
- AddRequestHeader=X-Request-Red, Blue-{segment}AddRequestParameter
GatewayFilter
Factory增加请求参数,主要接收
name
和value
两个参数,如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16spring:
cloud:
gateway:
routes:
- id: add_request_parameter_route
uri: https://example.org
filters:
# 增加请求参数
- AddRequestParameter=red, blue
- id: add_request_parameter_route2
uri: https://example.org
predicates:
- Host: {segment}.myhost.org
filters:
# 增加请求参数 url变量可以在value中引用 如下
- AddRequestParameter=foo, bar-{segment}AddResponseHeader
GatewayFilter
Factory增加响应头,主要接收
name
和value
两个参数,用法参考AddRequestParameter
DedupeResponseHeader
GatewayFilter
Factory去重响应头,主要接收
name
和另一个可选参数strategy
。如下:1
2
3
4
5
6
7
8
9spring:
cloud:
gateway:
routes:
- id: dedupe_response_header_route
uri: https://example.org
filters:
# 去重以下响应头
- DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-OriginDedupeResponseHeader过滤器还接受可选的策略参数
strategy
。值包含RETAIN_FIRST(默认值),RETAIN_LAST和RETAIN_UNIQUE。RETAIN_FIRST(默认值):保留第一个
RETAIN_LAST:保留最后一个
RETAIN_UNIQUE:仅保留唯一性 不相同的值都会保留
Hystrix
GatewayFilter
Factory由于Netflix的Hystrix已经不再更新。所以建议将Spring Cloud CircuitBreaker网关过滤器与Resilience4J一起使用,因为Spring Cloud Gateway将来的版本中将不再支持Hystrix。
Hystrix熔断支持的过滤器。Hystrix是Netflix的一个库,用于实现断路器模式。
Hystrix
GatewayFilter
将断路器引入网关路由,保护服务免受级联故障的影响,并在下游故障的情况下提供后备响应。要在项目中启用
Hystrix
GatewayFilter
实例,请添加对Spring Cloud Netflix的spring-cloud-starter-netflix-hystrix
的依赖。该过滤器工厂主要接收
name
单个参数,即HystrixCommand的名称。如下1
2
3
4
5
6
7
8
9
10spring:
cloud:
gateway:
routes:
- id: hystrix_route
uri: https://example.org
filters:
- Hystrix=myCommandName
hystrix.command.myCommandName.execution.isolation.thread.timeoutInMilliseconds: 5000Hystrix过滤器还可以接收可选的
fallbackUri
参数。当前,仅支持forward:
schema的URI。如果调用了fallback,则请求将转发到与URI匹配的控制器,forward即可以是网关的controller也可以是转发到其他路由。如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14spring:
cloud:
gateway:
routes:
- id: hystrix_route
uri: lb://backing-service:8088
predicates:
- Path=/consumingserviceendpoint
filters:
- name: Hystrix
args:
name: fallbackcmd
fallbackUri: forward:/incaseoffailureusethis
- RewritePath=/consumingserviceendpoint, /backingserviceendpointSpringCloudCircuitBreaker
FilterFactorySpringCloudCircuitBreakerFilterFactory
使用Spring Cloud CircuitBreaker API将网关路由包装在断路器中。 Spring Cloud CircuitBreaker支持可与Spring Cloud Gateway一起使用的两个库Hystrix
和Resilience4J
。由于Netflix已将Hystrix
置于仅维护模式,因此建议使用Resilience4J
。要启用Spring Cloud CircuitBreaker过滤器,您需要在类路径上放置
spring-cloud-starter-circuitbreaker-reactor-resilience4j
或spring-cloud-starter-netflix-hystrix
。以下示例配置了一个Spring Cloud CircuitBreaker GatewayFilter:1
2
3
4
5
6
7
8spring:
cloud:
gateway:
routes:
- id: circuitbreaker_route
uri: https://example.org
filters:
- CircuitBreaker=myCircuitBreaker要配置断路器,请参阅所使用的基础断路器实现的配置。
Spring Cloud CircuitBreaker过滤器还可以接受可选的
fallbackUri
参数。当前,仅支持forward:
schema的URI。如果调用了fallback,则请求将转发到与URI匹配的控制器。如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14spring:
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根据http状态触发熔断。
在某些情况下,您可能想根据断路器包装的路线返回的状态代码来使断路器熔断。断路器配置对象获取状态码列表,如果返回该状态码,则会导致断路器跳闸。设置要使断路器跳闸的状态码时,可以使用带状态码值的整数或HttpStatus枚举的String表示形式,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16spring:
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"FallbackHeaders
GatewayFilter
FactoryFallbackHeadersGatewayFilterFactory
允许在转发到外部应用中的fallbackUri的请求的请求头中添加Hystrix或Spring Cloud CircuitBreaker执行异常详细信息,如:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21spring:
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"
)
MapRequestHeader
GatewayFilter
FactoryMapRequestHeaderGatewayFilterFactory
接收fromHeader和toHeader参数,它创建一个新的请求头(toHeader),并从传入的HTTP请求中一个现有的请求头(fromHeader)中提取值。如果输入请求头不存在,则过滤器不起作用。如果新请求头已经存在,则其值将使用新值进行扩充。如下:1
2
3
4
5
6
7
8spring:
cloud:
gateway:
routes:
- id: map_request_header_route
uri: https://example.org
filters:
- MapRequestHeader=Blue, X-Request-Red这会将
X-Request-Red:<values>
请求头添加到下游请求中,并带有来自传入HTTP请求的Blue请求头的更新值。PrefixPath
GatewayFilter
FactoryPrefixPathGatewayFilterFactory
使用单个参数prefix
,如下:1
2
3
4
5
6
7
8spring:
cloud:
gateway:
routes:
- id: prefixpath_route
uri: https://example.org
filters:
- PrefixPath=/mypath这会将
/mypath
作为所有匹配请求的路径的前缀。因此,对/hello
的请求将发送到/mypath/hello
。PreserveHostHeader
GatewayFilter
FactoryPreserveHostHeaderGatewayFilterFactory
没有参数。此过滤器设置请求属性,路由过滤器将检查该请求属性,以确定是否应发送原始host
请求头,而不是由HTTP客户端确定的host
请求头。默认情况下,转发到下游时,host
请求头会被remove掉,如果需要保留,则使用该过滤器。1
2
3
4
5
6
7
8spring:
cloud:
gateway:
routes:
- id: preserve_host_route
uri: https://example.org
filters:
- PreserveHostHeaderRequestRateLimiter
GatewayFilter
Factory请求限流过滤器,使用RateLimiter实现来确定是否允许继续当前请求。如果不是,则返回HTTP 429-太多请求(默认)的状态。
该过滤器采用可选的
keyResolver
参数和特定于速率限制器的参数,keyResolver
是一个实现KeyResolver接口的bean。在配置中,使用SpEL按名称引用bean。#{@myKeyResolver}
是一个SpEL表达式,它引用一个名为myKeyResolver的bean。接口如下:1
2
3
4> 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
(正确或错误)和spring.cloud.gateway.filter.request-rate-limiter.empty-key
来调整此行为。状态代码属性。无法使用“快捷方式”配置RequestRateLimiter。下面的示例无效的:
1
2# INVALID SHORTCUT CONFIGURATION
spring.cloud.gateway.routes[0].filters[0]=RequestRateLimiter=2, 2, #{@userkeyresolver}RedisRateLimiter
的实现基于Stripe完成的。它需要使用spring-boot-starter-data-redis-active
Spring Boot启动器。使用的算法是 令牌桶算法.
redis-rate-limiter.replenishRate
属性是您希望用户每秒允许多少个请求,而没有任何丢弃的请求。这是令牌桶被填充的速率.redis-rate-limiter.burstCapacity
属性是允许用户在一秒钟内执行的最大请求数。这是令牌桶可以容纳的令牌数。将此值设置为零将阻止所有请求redis-rate-limiter.requestedTokens
属性是一个请求要花费多少个令牌。这是每个请求从存储桶中获取的令牌数,默认为1通过在
replenishRate
和burstCapacity
中设置相同的值可以实现稳定的速率。通过将burstCapacity
设置为高于replenishRate,可以允许临时突发
。在这种情况下,由于两次连续的突发会导致请求丢弃(HTTP 429-太多请求),因此需要在两次突发之间允许有一定的时间限制(根据replenishRate
)。以下配置了redis-rate-limiter:1
2
3
4
5
6
7
8
9
10
11
12
13> 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
>这定义了每个用户10的请求速率限制。允许突发20,但是在下一秒中,仅10个请求可用。 KeyResolver是获取用户请求参数的简单方法(请注意,不建议在生产环境中使用此参数)。
您还可以将速率限制器定义为实现RateLimiter接口的Bean。在配置中,可以使用SpEL按名称引用Bean。
#{@ myRateLimiter}
是一个SpEL表达式,它引用名为myRateLimiter的bean。以下清单定义了一个速率限制器,该限制器使用前面清单中定义的KeyResolver:1
2
3
4
5
6
7
8
9
10
11
12> spring:
> cloud:
> gateway:
> routes:
> - id: requestratelimiter_route
> uri: https://example.org
> filters:
> - name: RequestRateLimiter
> args:
> rate-limiter: "#{@myRateLimiter}"
> key-resolver: "#{@userKeyResolver}"
>RedirectTo
GatewayFilter
FactoryRedirectToGatewayFilterFactory
接收两个参数,即status
和url
。status
参数应该是300系列重定向HTTP代码,例如301
。url
参数应该是有效的URL。这是Location请求头的值。对于相对重定向,您应该使用uri:no://op
作为路由定义的uri。下面的示例配置一个RedirectTo GatewayFilter:1
2
3
4
5
6
7
8spring:
cloud:
gateway:
routes:
- id: prefixpath_route
uri: https://example.org
filters:
- RedirectTo=302, https://acme.orgRemoveRequestHeader
GatewayFilter
FactoryRemoveRequestHeaderGatewayFilterFactory
顾名思义,去掉响应头。接收一个name
参数。如1
2> - RemoveResponseHeader=X-Response-Foo
>要删除任何类型的敏感标头,应为可能要执行此操作的任何路由配置此过滤器。此外,可以使用
spring.cloud.gateway.default-filters
一次配置此过滤器,并将其应用于所有路由。RemoveRequestParameter
GatewayFilter
FactoryRemoveRequestParameterGatewayFilterFactory
去除请求参数,接收一个name
参数。如:1
2> - RemoveRequestParameter=red
>RewritePath
GatewayFilter
Factory该过滤器负责重写path,接收路径的
regexp
参数和replacement
参数。这使用Java正则表达式提供了一种灵活的方式来重写请求路径。在实际使用中会经常用到。如:1
2
3
4
5
6
7
8
9
10spring:
cloud:
gateway:
routes:
- id: rewritepath_route
uri: https://example.org
predicates:
- Path=/red/**
filters:
- RewritePath=/red(?<segment>/?.*), $\{segment}RewriteLocationResponseHeader
GatewayFilter
Factory该过滤器主要重写Location响应头,通常摆脱特定于后端的细节。它接收
stripVersionMode
,locationHeaderName
,hostValue
和protocolRegex
参数。如:1
2
3
4
5
6
7
8spring:
cloud:
gateway:
routes:
- id: rewritelocationresponseheader_route
uri: http://example.org
filters:
- RewriteLocationResponseHeader=AS_IN_REQUEST, Location, ,例如, 对于一个请求
POST api.example.com/some/object/name
,object-service.prod.example.net/v2/some/object/id
的Location
响应头 ,会被修改为api.example.com/some/object/id
.stripVersionMode
参数具有以下可能的值:NEVER_STRIP
,AS_IN_REQUEST
(默认值)和ALWAYS_STRIP
NEVER_STRIP
:即使原始请求路径不包含任何版本,也不会剥离该版本AS_IN_REQUEST
:仅当原始请求路径不包含任何版本时,才剥离该版本。ALWAYS_STRIP
:即使原始请求路径包含版本,也始终剥离版本。
hostValue
参数(如果提供)用于替换Location
响应头的host:port
部分。如果未提供,则使用Host
请求头的值。protocolRegex
参数必须是有效的正则表达式字符串,协议名称与之匹配。如果不匹配,则过滤器不执行任何操作。默认值为http|https|ftp|ftps
。RewriteResponseHeader
GatewayFilter
Factory该过滤器的作用是重新响应头,接收
name
,regexp
, 和replacement
三个参数。如:1
2> - RewriteResponseHeader=X-Response-Red, , password=[^&]+, password=***
>对于一个响应头的header值
/42?user=ford&password=omg!what&flag=true
, 会被重写为/42?user=ford&password=***&flag=true
SaveSession
GatewayFilter
FactorySaveSessionGatewayFilterFactory
是保存会话状态的过滤器factory,在向下游转发之前保存。特别是对于像 Spring Session 这种懒加载数据存储是需要确保保存会话状态的。如果您将Spring Security与Spring Session集成在一起,并希望确保信息安全的转发到远程进程,那么这一点至关重要。
配置方式:
1
2> - SaveSession
>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
命名空间中设置适当的属性。可以使用以下属性: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
属性,并用逗号分隔值。以下示例显示了如何执行此操作:1
2> spring.cloud.gateway.filter.secure-headers.disable=x-frame-options,strict-transport-security
>SetPath
GatewayFilter
FactorySetPathGatewayFilterFactory
接收一个template
参数,如:1
2
3
4
5
6
7
8
9
10spring:
cloud:
gateway:
routes:
- id: setpath_route
uri: https://example.org
predicates:
- Path=/red/{segment}
filters:
- SetPath=/{segment}以上示例 ,如请求
${GATEWAY_PATH}/red/abc
会设置为/abc
转发到下游。SetRequestHeader
GatewayFilter
Factory设置请求头,接收
name
和value
参数,如:1
2
3
4
5
6
7
8
9
10
11
12
13
14spring:
cloud:
gateway:
routes:
- id: setrequestheader_route
uri: https://example.org
filters:
- SetRequestHeader=X-Request-Red, Blue
- id: setrequestheader_route2
uri: https://example.org
predicates:
- Host: {segment}.myhost.org
filters:
- SetRequestHeader=foo, bar-{segment}SetResponseHeader
GatewayFilter
Factory设置响应头,接收
name
和value
两个参数,如:1
2
3
4
5
6
7
8
9
10
11
12
13
14spring:
cloud:
gateway:
routes:
- id: setresponseheader_route
uri: https://example.org
filters:
- SetResponseHeader=X-Response-Red, Blue
- id: setresponseheader_route2
uri: https://example.org
predicates:
- Host: {segment}.myhost.org
filters:
- SetResponseHeader=foo, bar-{segment}SetStatus
GatewayFilter
FactorySetStatusGatewayFilterFactory
接收单个参数status
。必须是SpringHttpStatus
中的值,既可以是数字如404
,也可以是枚举值如NOT_FOUND
。如下示例:1
2
3
4
5
6
7
8
9
10
11
12spring:
cloud:
gateway:
routes:
- id: setstatusstring_route
uri: https://example.org
filters:
- SetStatus=BAD_REQUEST
- id: setstatusint_route
uri: https://example.org
filters:
- SetStatus=401可以通过以下配置将原状态值附带到响应头中
1
2
3
4
5
6> spring:
> cloud:
> gateway:
> set-status:
> original-status-header-name: original-http-status
>StripPrefix
GatewayFilter
FactoryStripPrefixGatewayFilterFactory
是用来重写path的,主要功能:设置跳过前缀节数,接收一个参数parts
,该值是一个数字即转发到下游时需要跳过的path前缀节数。如:1
2
3
4
5
6
7
8
9
10spring:
cloud:
gateway:
routes:
- id: nameRoot
uri: https://nameservice
predicates:
- Path=/v1/name/**
filters:
- StripPrefix=2以上示例,当网关请求是
${gatewayUrl}/v1/name/zhangsan
会被跳过2节变成/zhangsan
转发下游服务。Retry
GatewayFilter
FactoryRetryGatewayFilterFactory
是重试过滤器,支持以下参数:retries
: 应尝试的重试次数。statuses
: 应重试的HTTP状态代码,值参考org.springframework.http.HttpStatus
.methods
: 应重试的Http methods,值参考org.springframework.http.HttpMethod
.series
: 要重试的状态码系列, 值参考org.springframework.http.HttpStatus.Series
.exceptions
: 应重试的异常。backoff
: 重试配置的指数补偿。在firstBackoff * (factor ^ n)
的退避间隔后执行重试,其中n是迭代。如果配置了maxBackoff
,则将应用的最大退避限制为maxBackoff
。如果basedOnPreviousValue
为true,则使用prevBackoff * factor
计算退避量。
如果启用了以下默认值,则为“重试”筛选器配置:
retries
: 3次series
: 5XX状态码系列methods
: GET methodexceptions
:IOException
andTimeoutException
backoff
: disabled
配置示例如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19spring:
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: falseRequestSize
GatewayFilter
Factory请求大小过滤器,过滤器接收
maxSize
参数。maxSize
是一种DataSize
类型,因此可以将值定义为一个数字,后跟一个可选的DataUnit
后缀,例如'KB'
或'M'
。字节的默认值为'B'
。它是请求的允许大小限制,以字节为单位。以下配置了RequestSize GatewayFilter:1
2
3
4
5
6
7
8
9
10
11
12spring:
cloud:
gateway:
routes:
- id: request_size_route
uri: http://localhost:8080/upload
predicates:
- Path=/upload
filters:
- name: RequestSize
args:
maxSize: 5000000当由于大小而拒绝请求时,会将响应状态设置为
413 Payload Too Large
,并带有附加报头errorMessage
。以下示例显示了这样的错误消息。1
2> errorMessage` : `Request size is larger than permissible limit. Request size is 6.0 MB where permissible limit is 5.0 MB
>如果未在路由定义中作为过滤器参数提供,则默认请求大小将设置为5 MB。
SetRequestHostHeader
GatewayFilter
Factory设置
Host
请求头,在某些情况下,可能需要覆盖Host
请求头。示例如下:1
2
3
4
5
6
7
8
9
10
11
12spring:
cloud:
gateway:
routes:
- id: set_request_host_header_route
uri: http://localhost:8080/headers
predicates:
- Path=/headers
filters:
- name: SetRequestHost
args:
host: example.orgModifyRequestBody
GatewayFilter
Factory修改请求body,只能使用Java DSL来配置此过滤器。如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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;
}
}ModifyResponseBody
GatewayFilter
Factory重写响应body,只能使用Java DSL来配置此过滤器。如下:
1
2
3
4
5
6
7
8
9
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();
}
三 让过滤器在全局生效
要添加过滤器并将其应用于所有路由,可以使用spring.cloud.gateway.default-filters。此属性采用过滤器列表。以下清单定义了一组默认过滤器:
1 | spring: |
四 自定义路由过滤器
通过了解框架自带的30多个路由过滤器,参考后可定义业务需要的路由过滤器。
自定义过滤器工厂继承
AbstractGatewayFilterFactory
<Config
>继承后重写
apply
方法如下,如果属性仅有name
和value
的可直接继承AbstractNameValueGatewayFilterFactory
,这样里面的Config也是可以复用的1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public GatewayFilter apply(Config config) {
return new GatewayFilter() {
public Mono<Void> filter(ServerWebExchange exchange,
GatewayFilterChain chain) {
// ... 具体业务逻辑
}
public String toString() {
// 重写toString...
}
};
}其中
Config
一般是自定义过滤器工厂的静态内部类,如果Config
只有一个name
属性可以复用父类AbstractGatewayFilterFactory
中定义的静态内部类NameConfig
,如1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21public static class Config {
private String regexp;
private String replacement;
public String getRegexp() {
return regexp;
}
public Config setRegexp(String regexp) {
Assert.hasText(regexp, "regexp must have a value");
this.regexp = regexp;
return this;
}
public String getReplacement() {
return replacement;
}
public Config setReplacement(String replacement) {
Assert.notNull(replacement, "replacement must not be null");
this.replacement = replacement;
return this;
}
}其中
Config
里的属性就是过滤器接收的参数定义。重写过滤器工厂的
shortcutFieldOrder
方法定义快捷方式的字段顺序,如下:1
2
3
4
public List<String> shortcutFieldOrder() {
return Arrays.asList(REGEXP_KEY, REPLACEMENT_KEY);
}重写过滤器工厂的
name()
方法可以自定义过滤器的名称,如果不重写,默认会使用工厂类的前缀(即GatewayFilterFactory
之前的类名部分)作为过滤器名称。默认情况如:1
RewritePathGatewayFilterFactory 的 过滤器名称 默认是 RewritePath
重写示例如:
1
2
3
4
public String name() {
return "CircuitBreaker";
}如果需要关心自定义过滤器在过滤器联调中的顺序位置,则有以下两种方式:
1 继承
org.springframework.core.Ordered
接口,实现getOrder,返回具体的order次序号,如果不设置,默认情况下,过滤器的顺序会从1开始按着Route中的定义依次排序。2 写
Order
注解最后,一个示例如下:
1 | public class PreGatewayFilterFactory extends AbstractGatewayFilterFactory<PreGatewayFilterFactory.Config> { |