二十四、GatewayFilter 工厂

路由过滤器GatewayFilter允许修改进来的HTTP请求内容或者返回的HTTP响应内容。路由过滤器的作用域是一个具体的路由配置。
Spring Cloud Gateway提供了丰富的内建的GatewayFilter工厂,可以按需选用 。

图 from: https://blog.csdn.net/forezp/article/details/85057268

过滤器的声明周期:

Gateway Filters

注意:接收端默认9999的服务中。

1. AddRequestHeader

AddRequestHeader GatewayFilter 工厂采用 namevalue 参数。

1
2
3
4
5
6
7
8
9
10
spring:
cloud:
gateway:
routes:
- id: gateway-filter
uri: http://localhost:9999
predicates:
- Path=/addRequestHeader
filters:
- AddRequestHeader= X-Request-username,admin

9999端口接收端:

1
2
3
4
5
@GetMapping(value = "/addRequestHeader")
public String addRequestHeader(@RequestHeader("X-Request-username") String username){
System.out.println("X-Request-username:"+username);
return "addRequestHeader SUCCESS";
}

说明:使用@RequestHeader注解读取HTTP Header中的数据。

当然,我们也可以使用路径变量的形式来动态传递参数。

1
2
3
4
5
6
7
8
9
10
spring:
cloud:
gateway:
routes:
- id: add_request_header_route
uri: http://localhost:9999
predicates:
- Path=/addRequestHeader/{username}
filters:
- AddRequestHeader= X-Request-username,u-{username}

接收端:

1
2
3
4
5
@GetMapping(value = "/addRequestHeader/{str}")
public String addRequestHeader(@RequestHeader("X-Request-username") String username){
System.out.println("X-Request-username:"+username);
return "addRequestHeader SUCCESS";
}

2. AddRequestParameter

AddRequestParameter GatewayFilter Factory同样是采用 namevalue .

1
2
3
4
5
6
7
8
9
10
spring:
cloud:
gateway:
routes:
- id: add_request_parameter_route
uri: http://localhost:9999
predicates:
- Path=/addRequestParameter
filters:
- AddRequestParameter= name,zhangsan

接收端:

1
2
3
4
5
@GetMapping(value = "/addRequestParameter")
public String addRequestParameter(@RequestParam("name") String name){
System.out.println("name:"+name);
return "addRequestParameter SUCCESS";
}

说明: 我们使用addRequestParamter filter来将参数信息添加到所有匹配请求的下游请求的请求参数中。同样也可以使用路径参数来动态传递,如下:

1
2
3
4
5
6
7
8
9
10
spring:
cloud:
gateway:
routes:
- id: add_request_parameter_route
uri: http://localhost:9999
predicates:
- Host= {str}.ouyanghao.com
filters:
- AddRequestParameter= name,{str}

这里记录一个异常信息:

1
2
reactor.core.Exceptions$ErrorCallbackNotImplemented: java.lang.IllegalArgumentException: Unable to find GatewayFilterFactory with name AddResponseHeader 
Caused by: java.lang.IllegalArgumentException: Unable to find GatewayFilterFactory with name AddResponseHeader

这个问题我之前以为是导包的问题,结果一顿操作之后,发现在配置过滤器的时候,不能中间加空格,即:

1
2
3
4
5
filters:
- AddResponseHeader = name,lisi
# 上面的写法是错误的,不能在等号之前加空格
filters:
- AddResponseHeader= name,lisi

3. AddResponseHeader

AddResponseHeader Filter Factory同样是采用两个参数 key (name)和 value 形式。

1
2
3
4
5
6
7
8
9
10
spring:
cloud:
gateway:
routes:
- id: add_response_header_route
uri: http://localhost:9999
predicates:
- Path=/addResponseHeader
filters:
- AddResponseHeader= name,lisi

说明: 这样会将name=list 头信息,添加到所有匹配请求的下游响应头中去。同样也可以使用路径参数来动态传递/user/{str}.

4. DedupeResponseHeader

DedupeResponseHeader Filter Factory 采用两个参数,一个是name,一个是策略,中间使用空格隔开,我们看一下源码上的注释:

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/*
Use case: Both your legacy backend and your API gateway add CORS header values. So, your consumer ends up with
Access-Control-Allow-Credentials: true, true
Access-Control-Allow-Origin: https://musk.mars, https://musk.mars
(The one from the gateway will be the first of the two.) To fix, add
DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin
用例:后端程序以及API网关都会往响应头中添加 CORS的头信息,所以,最终的消费者得到的就是具有重复值的,如上所述,所以此时我们需要将重复值去除。

Configuration parameters:
- name
String representing response header names, space separated. Required.
- strategy
RETAIN_FIRST - Default. Retain the first value only.
RETAIN_LAST - Retain the last value only.
RETAIN_UNIQUE - Retain all unique values in the order of their first encounter.
配置:
名字:响应头的名字,中间添加一个必须的空格。
策略:1.保留第一个,2.保留最后一个,3.保留所有唯一值,以它们第一次出现的顺序保留。

Example 1
default-filters:
- DedupeResponseHeader=Access-Control-Allow-Credentials

Response header Access-Control-Allow-Credentials: true, false
Modified response header Access-Control-Allow-Credentials: true

Example 2
default-filters:
- DedupeResponseHeader=Access-Control-Allow-Credentials, RETAIN_LAST

Response header Access-Control-Allow-Credentials: true, false
Modified response header Access-Control-Allow-Credentials: false

Example 3
default-filters:
- DedupeResponseHeader=Access-Control-Allow-Credentials, RETAIN_UNIQUE

Response header Access-Control-Allow-Credentials: true, true
Modified response header Access-Control-Allow-Credentials: true
*/

public class DedupeResponseHeaderGatewayFilterFactory extends
AbstractGatewayFilterFactory<DedupeResponseHeaderGatewayFilterFactory.Config> {}

上面的注释已经解释了问题。

1
2
3
4
5
6
7
8
9
10
spring:
cloud:
gateway:
routes:
- id: dedupe_response_header_route
uri: http://localhost:9999
predicates:
- Path=/dedupeResponseHeader
filters:
- DedupeResponseHeader= Access-Control-Allow-Credentials Access-Control-Allow-Origin, RETAIN_FIRST

剔除重复的响应头信息。

5. Hystrix

Hystrix 是 netflix下的熔断组件,由于已经停止维护,并且这里主要是使用SpringCloudAlibaba系列,使用的是Sentinel,所以这里不详述,就简单把官方示例放在这,后面用来再回来看。

Hystrix是Netflix的一个库,用于实现断路器模式。Hystrix GatewayFilter允许您将断路器引入网关路由,保护您的服务免受级联故障的影响,并允许您在下游故障的情况下提供后备响应。

1
2
3
4
5
6
7
8
spring:
cloud:
gateway:
routes:
- id: hystrix_route
uri: https://example.org
filters:
- Hystrix=myCommandName

6. FallbackHeaders

FallbackHeaders工厂可以让你在转发到请求的头部添加Hystrix执行异常的详细信息fallbackUri在以下情况下在外部应用程序,如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
spring:
cloud:
gateway:
routes:
- id: ingredients
uri: lb://ingredients
predicates:
- Path=//ingredients/**
filters:
- name: Hystrix
args:
name: fetchIngredients
fallbackUri: forward:/fallback
- id: ingredients-fallback
uri: http://localhost:9994
predicates:
- Path=/fallback
filters:
- name: FallbackHeaders
args:
executionExceptionTypeHeaderName: Test-Header

7. MapRequestHeader

MapRequestHeader GatewayFilter 工厂采用两个参数:fromHeadertoHeader.

1
2
3
4
5
6
7
8
9
10
spring:
cloud:
gateway:
routes:
- id: map_request_header_route
uri: http://localhost:9999
predicates:
- Path=/mapRequestHeader
filters:
- MapRequestHeader= password, X-Request-username

说明: fromHeadertoHeader 在上例中分别为 passwordX-Request-username .

接收端:

1
2
3
4
5
6
7
@GetMapping(value = "/mapRequestHeader")
public String mapRequestHeader(
@RequestHeader(value = "password", required = false) String password,
@RequestHeader(value = "X-Request-username", required = false) String username){
System.out.println("username:"+username + " | password:"+password);
return "mapRequestHeader Success";
}

我们下面来测试一下:

后台结果如下:

1
username:admin,123456 | password:123456

可以看出,password 将值注入到了 X-Request-username . 即将请求的头信息添加到后续的下游请求中。

8. PrefixPath

PrefixPath GatewayFilter工厂采用单个prefix参数。

1
2
3
4
5
6
7
8
9
10
spring:
cloud:
gateway:
routes:
- id: prefix_path_route
uri: http://localhost:9999
Predicates:
Method= GET
filters:
- PrefixPath=/user

我们通过下面的命令可以将请求转发到 http://localhost:9999/user/name

1
curl localhost:8080/name

接收端:

1
2
3
4
@GetMapping(value = "/user/name")
public String useName(){
return "prefixPath success";
}

9. PreserveHostHeader

我们从字面意思可以知道:保护Host Header,其实就是保护请求头中的Host字段。PreserveHostHeader 不需要参数。此过滤器将检查该请求属性,以确定是否应发送原始主机头,而不是由HTTP客户端确定的主机头。

如下:

1
2
3
4
5
6
7
8
9
10
spring:
cloud:
gateway:
routes:
- id: prefix_path_route
uri: http://localhost:9999
Predicates:
Method= GET
filters:
- PreserveHostHeader

接收端:

1
2
3
4
5
6
@GetMapping(value = "/preserveHostHeader")
public String preserveHostHeader(@RequestHeader(value = "Host", required = false)
String host){
System.out.println("host:"+host);
return "preserveHostHeader success";
}

在浏览器地址栏输入:http://localhost:8080/preserveHostHeader,接收端显示结果:

1
2
host:localhost:8080,localhost:8080
//会把Host存到请求头中

10. RequestRateLimiter

RequestRateLimiter:请求速率限制器。RequestRateLimiter GatewayFilter 工厂是一个RateLimiter 的实现类,用它去决定当前请求是否允许继续执行。如果不允许继续执行,默认会返回一个 HTTP 429 - Too Many Requests (太多连接状态)。

这个filter采用 一个可选的keyResolver 参数 和 指定的速率限制器参数。

keyResolver 是一个实现了KeyResolver接口的实现类的bean。在配置中,使用SpEL按名称引用bean.

#{@myKeyResolver}SpEL表达式,它引用名称为myKeyResolver的bean。

KeyResolver.java 源码:

1
2
3
public interface KeyResolver {
Mono<String> resolve(ServerWebExchange exchange);
}

KeyResolver接口允许一个可拔插策略去驱动如何限制请求。

有一个默认实现:

1
2
3
4
5
6
7
8
9
public class PrincipalNameKeyResolver implements KeyResolver {
public static final String BEAN_NAME = "principalNameKeyResolver";

@Override
public Mono<String> resolve(ServerWebExchange exchange) {
return exchange.getPrincipal().map(Principal::getName)
.switchIfEmpty(Mono.empty());
}
}

从上面的代码可以看出:默认的keyResolver 的实现是从 ServerWebExchange 取得Principal 并且回调Principal.getName() 方法。

默认情况下,如果 KeyResolver 没有找到一个key,那么请求将会被拒绝。当然,可以通过 spring.cloud.gateway.filter.request-rate-limiter.deny-empty-key (true or false) 以及 spring.cloud.gateway.filter.request-rate-limiter.empty-key-status-code 属性来设置。

10.1 Redis RateLimiter

redis 实现基于Stripe所做的工作。需要导入相关依赖,注意版本要求,参考spring官网。

https://spring.io/projects/spring-cloud

1
2
3
4
5
6
7
8
9
10
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>

<!--监控依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

配置类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Configuration
public class GatewayConfiguration {

//根据请求路径限流 getPath
@Bean
public KeyResolver keyResolver(){
return new KeyResolver() {
@Override
public Mono<String> resolve(ServerWebExchange exchange) {
return Mono.just(exchange.getRequest().getPath().toString());
}
};
}


// 基于请求参数的限流
@Bean
public KeyResolver userKeyResolver(){
return exchange -> Mono.just(
exchange.getRequest().getQueryParams().getFirst("userId")
);
}

}

上面的例子是获取到官网的,就是在请求中获取一个叫user的请求参数,用于统计。

SpringCloud Gateway的限流方式是基于令牌桶算法的,使用Redis来存储Key。

配置信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
spring:
cloud:
gateway:
routes:
- id: request_hrate_limiter
uri: http://localhost:9999
Predicates:
Method= GET
filters:
# 使用限流过滤器
- name: RequestRateLimiter
args:
key-resolver: "#{@userKeyResolver}"
redis-rate-limiter.replenishRate: 2
redis-rate-limiter.burstCapacity: 2
redis:
host: 127.0.0.1
port: 6379

说明:

  • redis-rate-limiter.replenishRate : 向令牌桶中填充的速率(一秒放多少个令牌)
  • redis-rate-limiter.burstCapacity : 允许用户在一秒内执行的最大请求数。将此值设置为0,将阻止所有请求。(令牌桶的容量)

为实现一个稳定的速率,通常将上述两个属性设置成相同的值,将burstCapacity 设置大于 replenishRate 可以允许临时暴发。在这种情况下,需要在突发之间允许速率限制器一段时间(根据replenishRate ),因为连续两次突发可能导致请求被丢弃(HTTP 429 - Too Many Requests)

上面的userKeyResolver 是一个简单的获取用户请求参数(注意:不建议用在生产)

速率限制器也可以定义为实现了 RateLimiter 接口的bean。在配置中,使用SpEL按名称引用bean。#{@myRateLimiter} 是SpEL表达式,它引用名称为myRateLimiter的bean。

1
2
3
4
5
6
7
8
9
10
11
spring:
cloud:
gateway:
routes:
- id: requestratelimiter_route
uri: https://example.org
filters:
- name: RequestRateLimiter
args:
rate-limiter: "#{@myRateLimiter}"
key-resolver: "#{@userKeyResolver}"

11. RedirectTo

RedirectTo:重定向到。RedirectTo GatewayFilter工厂采用两个参数:statusurl。这个状态码需要是一个300系列的重定向的HTTP状态码。例如:301. url应该是一个有效的地址,将设置为头部的Location的值。

application.yaml

1
2
3
4
5
6
7
8
9
10
spring:
cloud:
gateway:
routes:
- id: request_hrate_limiter
uri: http://localhost:9999
Predicates:
Method= GET
filters:
- RedirectTo= 302, http://www.163.com

上面配置,当我们访问http://localhost:8080/redirectTo 路径时,并不会映射到http://localhost:9999/redirectTo.而是被转发到了http://www.163.com.

12. RemoveHopByHopHeadersFIlter

RemoveHopByHopHeadersFilter GatewayFilter工厂从转发的请求中删除header,被删除的header列表来自IETF。

默认删除的header是:

  1. Connection
  2. Keep-Alive
  3. Proxy-Authenticate
  4. Proxy-Authorization
  5. TE
  6. Trailer
  7. Transfer-Encoding
  8. Upgrade

如果希望去修改它,可以通过设置spring.cloud.gateway.filter.remove-non-proxy-headers.headers属性来移除header列表。

13. RemoveRequestHeader

RemoveRequestHeader GatewayFilter 工厂采用一个参数:name. 请求头中的指定名字的值将被移除。

application.yaml

1
2
3
4
5
6
7
8
9
10
spring:
cloud:
gateway:
routes:
- id: remove_request_header
uri: http://localhost:9999
Predicates:
Method= GET
filters:
- RemoveRequestHeader=username

接收端:

1
2
3
4
5
6
@GetMapping(value = "/removeRequestHeader")
public String removeRequestHeader(
@RequestHeader(value = "username", required = false) String username){
System.out.println("username:"+username);
return "removeRequestHeader success";
}

测试:

请求是携带了username 参数,下面是接收端打印的结果:

1
username:null

14. RemoveResponseHeader

见名知意,在返回客户端之前,删除指定响应头的数据。RemoveResponseHeader GatewayFilter 工厂采用一个参数:name .

1
2
3
4
5
6
7
8
9
10
spring:
cloud:
gateway:
routes:
- id: remove_response_header
uri: http://localhost:9999
Predicates:
Method= GET
filters:
- RemoveResponseHeader=Content-Type

上面的配置可以从响应头中删除 Content-Type 头信息,然后将其返回到客户端。

要删除任何类型的敏感信息,你可以需要配置这个filter在你需要的任何路由上,当然,我们可以在配置文件中配置spring.cloud.gateway.default-filters, 那么可以引用在所有的路由上。

15. RemoveRequestParameter

RemoveRequestParameter GatewayFilter 工厂采用一个参数:name . 指定请求参数将会被删除。

这个是新版本2.2.0.RC1中新加的.

1
2
3
4
5
6
7
8
9
10
spring:
cloud:
gateway:
routes:
- id: remove_response_parameter
uri: http://localhost:9999
Predicates:
Method= GET
filters:
- RemoveRequestParameter=username

以上代码可以从请求参数中删除指定参数,在进行路由。

16. RewritePath

RewritePath Gateway采用路径 正常表达式和替换参数。使用正则表达式可以灵活地重写请求路径。

application.yaml

1
2
3
4
5
6
7
8
9
10
spring:
cloud:
gateway:
routes:
- id: remove_response_parameter
uri: http://localhost:9999
Predicates:
Method= GET
filters:
- RewritePath=/user/(?<str>.*), /$\{str}

根据上面的配置,使用路径http://localhost:8080/user/rewritePath 会被映射到 http://localhost:9999/rewritePath.

注意: 由于YAML规范,$\替换为$

17. RewriteLocationResponseHeader

RewriteLocationResponseHeader GatewayFilter 工厂 用来重写 响应头的Location 的值,以摆脱后端特定的详细信息。这需要 stripVersionMode , locationHeaderName , hostValueprotocolsRegex 参数。

1
2
3
4
5
6
7
8
spring:
cloud:
gateway:
routes:
- id: rewritelocationresponseheader_route
uri: http://example.org
filters:
- RewriteLocationResponseHeader=AS_IN_REQUEST, Location, ,

示例:对于请求api.example.com/some/object/name. Location 响应头的值object-service.prod.example.net/v2/some/object/id 将会被重写为api.example.com/some/object/id

解释:由于hostValueprotocolsRegex 参数都没有提供,所以使用原请求的host,并且stripVersionMode 选择的是AS_IN_REQUEST , 所以在原请求路径不包含版本时,将版本剥离删除。

步骤:

  1. api.example.com/some/object/name
  2. api.example.com/v2/some/object/id
  3. 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 必须是有效的正则表达式字符串,协议名称将与该regex 匹配。如果不匹配,过滤器将不执行任何操作。默认值为 http|https|ftp|ftps.

18. RewriteResponseHeader

RewriteResponseHeader GatewayFilter 工厂采用三个参数,分别为:name, regexpreplacement . 它使用Java正则表达式以灵活的方式来重写响应头的值。

1
2
3
4
5
6
7
8
spring:
cloud:
gateway:
routes:
- id: rewriteresponseheader_route
uri: https://example.org
filters:
- RewriteResponseHeader=X-Response-Foo, , password=[^&]+, password=***

对于响应头值 /42?user=ford&password=omg!what&flag=true , 在下游请求执行之后将被设置为 /42?user=ford&password=***&flag=true ,在YAML文件中,需要使用$\ 来表示$.

19. SaveSession

SaveSession GatewayFilter 工厂在向下游转发调用之前会强制执行 WebSession::save 操作。 这在将Spring Session之类的东西与惰性数据存储一起使用时特别有用,并且需要确保在进行转发呼叫之前已保存会话状态。

application.yaml

1
2
3
4
5
6
7
8
9
10
spring:
cloud:
gateway:
routes:
- id: save_session
uri: https://example.org
predicates:
- Path=/foo/**
filters:
- SaveSession

如果您将Spring Security与Spring Session 集成在一起,并且想要确保安全性详细信息已转发到远程进程,那么这一点至关重要。

20. SecureHeaders

SecureHeaders GatewayFilter 工厂添加了许多头到响应中。

文档: https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.0.RC1/reference/html/#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
  • frame-options
  • content-type-options
  • referrer-policy
  • content-security-policy
  • download-options
  • permitted-cross-domain-policies

要禁用默认值,请将该属性设置为spring.cloud.gateway.filter.secure-headers.disable逗号分隔的值。

例:

1
spring.cloud.gateway.filter.secure-headers.disable=frame-options,download-options

21. SetPath

SetPath GatewayFilter 采用路径template 参数。通过允许路径的模板片段,提供了一种操作请求路径的简单方法。这使用了Spring Framework 中的uri模板。允许多个匹配片段。

application.yaml

1
2
3
4
5
6
7
8
9
10
spring:
cloud:
gateway:
routes:
- id: remove_response_parameter
uri: http://localhost:9999
Predicates:
- Path= /set/{subUrl}
filters:
- SetPath= /{subUrl}

对于请求路径 /set/path ,路径会被设置为/path 然后在转发到下游请求。

22. SetRequestHeader

SetRequestHeader GatewayFilter 工厂采用 namevalue 参数。

application.yaml

1
2
3
4
5
6
7
8
9
10
spring:
cloud:
gateway:
routes:
- id: set_request_header
uri: http://localhost:9999
Predicates:
- Method=GET
filters:
- SetRequestHeader= username,admin

以上设置,可以将请求头中的username 的原来值修改为admin.

接收端:

1
2
3
4
5
6
@GetMapping(value = "/setRequestHeader")
public String setRequestHeader(
@RequestHeader(value = "username", required = false) String username){
System.out.println("username:"+username);
return "setRequestHeader success";
}

postman测试:

测试结果:

1
username:admin

上述测试可以看出,SetRequestHeader 和前面的AddRequestHeader 不同,这个是将原来的值替换为配置的值。

23. SetResponseHeader

SetResponseHeader GatewayFilter 工厂采用两个参数:namevalue .

application.yaml

1
2
3
4
5
6
7
8
9
10
spring:
cloud:
gateway:
routes:
- id: set_request_header
uri: http://localhost:9999
Predicates:
- Method=GET
filters:
- SetResponseHeader= X-Response-username,admin

这个过滤器主要是将 响应头中的 X-Response-username 替换为 admin .同样也可以使用路径参数动态传递。

24. SetStatus

SetStatus GatewayFilter工厂采用一个参数:status , 这个参数必须是一个有效的Spring HttpStatus . 它可以是整数值 404 或是枚举的字符串表示形式NOT_FOUND.

application.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
spring:
cloud:
gateway:
routes:
- id: set_status1
uri: http://localhost:9999
Predicates:
- Method=GET
filters:
- SetStatus= NOT_FOUND
- id: set_status2
uri: http://localhost:9999
Predicates:
- Method=GET
filters:
- SetStatus= 404

无论上述情况的哪一种,响应的HTTP状态都讲设置为404.

SetStatus GatewayFilter可以被 配置为响应头中从代理请求返回原始HTTP状态码,如果使用以下属性配置header,则会将其添加到响应头中:

1
2
3
4
5
spring:
cloud:
gateway:
set-status:
original-status-header-name: original-http-status

25. StripPrefix

StripPrefix GatewayFilter工厂采用一个参数:part , 这个参数在请求转发到下游之前去除路径的前 part 部分。

1
2
3
4
5
6
7
8
9
10
spring:
cloud:
gateway:
routes:
- id: strip_prefix
uri: http://localhost:9999
Predicates:
- Method=GET
filters:
- StripPrefix= 2

根据以上配置,可以将/user/name/stripPrefix 地址 切除前面两段,所以最后转发到下游的地址是/stripPrefix.

26. Retry

Retry GatewayFilter 工厂重试机制,参考官网:

https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.0.RC1/reference/html/#retry-gatewayfilter-factory

27. RequestSize

当请求大小高于允许的限制大小时,RequestSize GatewayFilter工厂将会阻止转发到下游服务。过滤器将RequestSize 参数作为请求的允许大小限制(以字节为单位)

application.yaml

1
2
3
4
5
6
7
8
9
10
11
12
spring:
cloud:
gateway:
routes:
- id: request_size_route
uri: http://localhost:8080/upload
predicates:
- Path=/upload
filters:
- name: RequestSize
args:
maxSize: 5000000

当请求由于大小而被拒绝时,RequestSize GatewayFilter 工厂将响应状态设置为 403 Payload Too Large 并带有head名为errorMessage 的数据。如下:

1
errorMessage: Request size is larger than permissible limit. Request size is 6.0 MB where permissible limit is 5.0MB

如果未在路由定义中作为过滤器参数提供,则默认请求大小设置为5MB。

28. Modify Request Body

这个过滤器用于在将请求转发到下游服务之前,将请求体进行修改。

注意:只能通过java来配置此过滤器。

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
@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;
}
}

29. Modify Response Body

该过滤器在响应发送会客户端之前,对响应体进行修改。同样也只支持Java配置。

1
2
3
4
5
6
7
8
9
@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();
}

30. Default Filter

如果想添加一个过滤器去应用在所有的路由上,可以使用 spring.cloud.gateway.default-filters 来配置,这个属性接收一个Filter列表。

application.yaml

1
2
3
4
5
6
spring:
cloud:
gateway:
default-filters:
- AddResponseHeader=X-Response-Default-Foo, Default-Bar
- PrefixPath=/httpbin

总结:这一节主要介绍SpringCloud Gateway中的过滤器。官方文档如下:

https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.0.RC1/reference/html/#gatewayfilter-factories

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×