6.GatewayFilter工厂

路由筛选器允许以某种方式修改传入的 HTTP 请求或传出的 HTTP 响应。 路由过滤器的范围限定为特定路由。 Spring Cloud 网关包括许多内置的 GatewayFilter 工厂。spring-doc.cadn.net.cn

有关如何使用以下任何筛选器的更详细示例,请查看单元测试

6.1. 使用AddRequestHeader GatewayFilter

AddRequestHeader GatewayFilterfactory 采用namevalue参数。 以下示例将AddRequestHeader GatewayFilter:spring-doc.cadn.net.cn

例 14.application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: add_request_header_route
        uri: https://example.org
        filters:
        - AddRequestHeader=X-Request-red, blue

此列表添加了X-Request-red:blueheader 添加到所有匹配请求的下游请求标头中。spring-doc.cadn.net.cn

AddRequestHeader知道用于匹配路径或主机的 URI 变量。 URI 变量可以在值中使用,并在运行时扩展。 以下示例将AddRequestHeader GatewayFilter,它使用一个变量:spring-doc.cadn.net.cn

例 15.application.yml
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 GatewayFilterFactory 采用namevalue参数。 以下示例将AddRequestParameter GatewayFilter:spring-doc.cadn.net.cn

例 16.application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: add_request_parameter_route
        uri: https://example.org
        filters:
        - AddRequestParameter=red, blue

这将添加red=blue添加到所有匹配请求的下游请求的查询字符串中。spring-doc.cadn.net.cn

AddRequestParameter知道用于匹配路径或主机的 URI 变量。 URI 变量可以在值中使用,并在运行时扩展。 以下示例将AddRequestParameter GatewayFilter,它使用一个变量:spring-doc.cadn.net.cn

例 17.application.yml
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 GatewayFilterFactory 采用namevalue参数。 以下示例将AddResponseHeader GatewayFilter:spring-doc.cadn.net.cn

例 18.application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: add_response_header_route
        uri: https://example.org
        filters:
        - AddResponseHeader=X-Response-Red, Blue

这增加了X-Response-Red:Blueheader 添加到所有匹配请求的下游响应的标头中。spring-doc.cadn.net.cn

AddResponseHeader知道用于匹配路径或主机的 URI 变量。 URI 变量可以在值中使用,并在运行时扩展。 以下示例将AddResponseHeader GatewayFilter,它使用一个变量:spring-doc.cadn.net.cn

例 19.application.yml
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-doc.cadn.net.cn

例 20.application.yml
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-CredentialsAccess-Control-Allow-Origin响应标头(如果网关 CORS 逻辑和下游逻辑都添加了它们)。spring-doc.cadn.net.cn

DedupeResponseHeaderfilter 还接受可选的strategy参数。 接受的值为RETAIN_FIRST(默认)、RETAIN_LASTRETAIN_UNIQUE.spring-doc.cadn.net.cn

6.5. Spring Cloud CircuitBreaker GatewayFilter 工厂

Spring Cloud CircuitBreaker GatewayFilter工厂使用 Spring Cloud CircuitBreaker API 将网关路由包装在 断路器。Spring Cloud CircuitBreaker 支持多个可与 Spring Cloud Gateway 一起使用的库。Spring Cloud 支持开箱即用的 Resilience4J。spring-doc.cadn.net.cn

要启用 Spring Cloud CircuitBreaker 过滤器,您需要将spring-cloud-starter-circuitbreaker-reactor-resilience4j在 Classpath 上。 下面的示例配置一个 Spring Cloud CircuitBreakerGatewayFilter:spring-doc.cadn.net.cn

例 21.application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: circuitbreaker_route
        uri: https://example.org
        filters:
        - CircuitBreaker=myCircuitBreaker

要配置断路器,请参阅您正在使用的底层断路器实现的配置。spring-doc.cadn.net.cn

Spring Cloud CircuitBreaker过滤器也可以接受可选的fallbackUri参数。 目前,只有forward:支持方案化 URI。 如果调用了回退,则请求将转发到与 URI 匹配的控制器。 以下示例配置了此类回退:spring-doc.cadn.net.cn

例 22.application.yml
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 中执行相同的作:spring-doc.cadn.net.cn

例 23.Application.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前缀)。spring-doc.cadn.net.cn

主要方案是使用fallbackUri在 Gateway 应用程序中定义内部控制器或处理程序。 但是,您也可以将请求重新路由到外部应用程序中的控制器或处理程序,如下所示:spring-doc.cadn.net.cn

例 24.application.yml
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-doc.cadn.net.cn

如果请求被转发到回退,Spring Cloud CircuitBreaker 网关过滤器还提供Throwable这就是造成它的原因。 它被添加到ServerWebExchange作为ServerWebExchangeUtils.CIRCUITBREAKER_EXECUTION_EXCEPTION_ATTR在 Gateway 应用程序中处理回退时可以使用的属性。spring-doc.cadn.net.cn

对于外部控制器/处理程序方案,可以添加包含异常详细信息的标头。 你可以在FallbackHeaders GatewayFilter Factory部分找到有关执行此作的更多信息。spring-doc.cadn.net.cn

6.5.1. 在状态代码上使断路器跳闸

在某些情况下,您可能希望根据状态代码触发断路器 从它包装的路由返回。断路器配置对象采用 状态代码,如果返回,将导致断路器跳闸。在设置 状态代码 您希望使断路器跳闸,您可以使用带有状态代码的整数 value 或HttpStatus列举。spring-doc.cadn.net.cn

例 25.application.yml
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"
例 26.Application.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").addStatusCode("INTERNAL_SERVER_ERROR"))
                .rewritePath("/consumingServiceEndpoint", "/backingServiceEndpoint")).uri("lb://backing-service:8088")
        .build();
}

6.6. 使用FallbackHeaders GatewayFilter

FallbackHeadersfactory允许你在转发到fallbackUri在外部应用程序中,如以下方案所示:spring-doc.cadn.net.cn

例 27.application.yml
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. 具有异常类型、消息和(如果可用)根本原因异常类型和消息的标头由FallbackHeadersFilter。spring-doc.cadn.net.cn

您可以通过设置以下参数的值(以默认值显示)来覆盖配置中标头的名称:spring-doc.cadn.net.cn

有关断路器和网关的更多信息,请参阅 Spring Cloud CircuitBreaker Factory 部分spring-doc.cadn.net.cn

6.7. 使用MapRequestHeader GatewayFilter

MapRequestHeader GatewayFilter工厂取fromHeadertoHeader参数。 它会创建一个新的命名标头 (toHeader),并且该值将从现有的命名标头 (fromHeader) 从传入的 HTTP 请求中获取。 如果 input 标头不存在,则筛选器不会产生任何影响。 如果新的命名标头已存在,则其值将使用新值进行扩充。 以下示例将MapRequestHeader:spring-doc.cadn.net.cn

例 28.application.yml
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页眉。spring-doc.cadn.net.cn

6.8. 该PrefixPath GatewayFilter

PrefixPath GatewayFilterfactory 将单个prefix参数。 以下示例将PrefixPath GatewayFilter:spring-doc.cadn.net.cn

例 29.application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: prefixpath_route
        uri: https://example.org
        filters:
        - PrefixPath=/mypath

这将作为/mypath添加到所有匹配请求的路径中。 因此,对/hello将被发送到/mypath/hello.spring-doc.cadn.net.cn

6.9. 使用PreserveHostHeader GatewayFilter

PreserveHostHeader GatewayFilterfactory 没有参数。 此筛选器设置路由筛选器检查的请求属性,以确定是否应发送原始主机标头,而不是由 HTTP 客户端确定的主机标头。 以下示例将PreserveHostHeader GatewayFilter:spring-doc.cadn.net.cn

例 30.application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: preserve_host_route
        uri: https://example.org
        filters:
        - PreserveHostHeader

6.10. 使用RequestRateLimiter GatewayFilter

RequestRateLimiter GatewayFilterfactory 使用RateLimiterimplementation 来确定是否允许当前请求继续。如果不是,则状态为HTTP 429 - Too Many Requests(默认情况下)。spring-doc.cadn.net.cn

此过滤器采用可选的keyResolver参数和特定于 Rate Limiter 的参数(本节稍后将介绍)。spring-doc.cadn.net.cn

keyResolver是一个 Bean,它实现了KeyResolver接口。 在配置中,使用 SPEL 按名称引用 bean。#{@myKeyResolver}是一个 SPEL 表达式,它引用名为myKeyResolver. 下面的清单显示了KeyResolver接口:spring-doc.cadn.net.cn

例 31.KeyResolver.java
public interface KeyResolver {
    Mono<String> resolve(ServerWebExchange exchange);
}

KeyResolverinterface 允许可插拔策略派生用于限制请求的 key。 在未来的里程碑版本中,将有一些KeyResolver实现。spring-doc.cadn.net.cn

的默认实现KeyResolverPrincipalNameKeyResolver,它会检索PrincipalServerWebExchange并调用Principal.getName().spring-doc.cadn.net.cn

默认情况下,如果KeyResolver找不到键,则请求被拒绝。 您可以通过设置spring.cloud.gateway.filter.request-rate-limiter.deny-empty-key (truefalse) 和spring.cloud.gateway.filter.request-rate-limiter.empty-key-status-code性能。spring-doc.cadn.net.cn

RequestRateLimiter不能使用 “shortcut” 表示法进行配置。以下示例无效spring-doc.cadn.net.cn

例 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-reactiveSpring Boot Starters。spring-doc.cadn.net.cn

redis-rate-limiter.replenishRateproperty 是您希望用户每秒执行的请求数,而不丢弃任何请求。 这是填充令牌桶的速率。spring-doc.cadn.net.cn

redis-rate-limiter.burstCapacityproperty 是允许用户在一秒钟内执行的最大请求数。 这是令牌桶可以容纳的令牌数量。 将此值设置为 0 会阻止所有请求。spring-doc.cadn.net.cn

redis-rate-limiter.requestedTokensproperty 是请求花费的令牌数量。 这是每个请求从存储桶中获取的令牌数,默认为1.spring-doc.cadn.net.cn

通过在replenishRateburstCapacity. 可以通过设置burstCapacity高于replenishRate. 在这种情况下,需要在突发之间允许速率限制器有一段时间(根据replenishRate),因为两个连续的突发将导致丢弃请求 (HTTP 429 - Too Many Requests). 下面的清单配置了redis-rate-limiter:spring-doc.cadn.net.cn

速率限制如下1 request/s通过设置replenishRate添加到所需的请求数,requestedTokens设置为时间跨度(以秒为单位),并将burstCapacity到产品replenishRaterequestedTokens,例如设置replenishRate=1,requestedTokens=60burstCapacity=60将导致1 request/min.spring-doc.cadn.net.cn

例 33.application.yml
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:spring-doc.cadn.net.cn

例 34.Config.java
@Bean
KeyResolver userKeyResolver() {
    return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));
}

这将每个用户的请求速率限制为 10。允许突增 20 个,但在下一秒,只有 10 个请求可用。 这KeyResolver是一个简单的 API,它得到userrequest 参数(请注意,不建议将此选项用于生产)。spring-doc.cadn.net.cn

您还可以将速率限制器定义为实现RateLimiter接口。 在配置中,您可以使用 SpEL 按名称引用 Bean。#{@myRateLimiter}是一个 SPEL 表达式,它引用一个 bean 的命名myRateLimiter. 下面的清单定义了一个速率限制器,它使用KeyResolver在前面的清单中定义:spring-doc.cadn.net.cn

例 35.application.yml
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 GatewayFilterfactory 接受两个参数,statusurl. 这statusparameter 应为 300 系列重定向 HTTP 代码,例如 301。 这urlparameter 应为有效的 URL。 这是Location页眉。 对于相对重定向,您应该使用uri: no://op作为路由定义的 URI。 下面的清单配置了RedirectTo GatewayFilter:spring-doc.cadn.net.cn

例 36.application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: prefixpath_route
        uri: https://example.org
        filters:
        - RedirectTo=302, https://acme.org

这将发送一个状态 302,其中包含一个Location:https://acme.org标头执行重定向。spring-doc.cadn.net.cn

6.12. 使用RemoveRequestHeaderGatewayFilter 工厂

RemoveRequestHeader GatewayFilterfactory 采用name参数。 它是要删除的标头的名称。 下面的清单配置了RemoveRequestHeader GatewayFilter:spring-doc.cadn.net.cn

例 37.application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: removerequestheader_route
        uri: https://example.org
        filters:
        - RemoveRequestHeader=X-Request-Foo

这会删除X-Request-Foo标头。spring-doc.cadn.net.cn

6.13.RemoveResponseHeader GatewayFilter

RemoveResponseHeader GatewayFilterfactory 采用name参数。 它是要删除的标头的名称。 下面的清单配置了RemoveResponseHeader GatewayFilter:spring-doc.cadn.net.cn

例 38.application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: removeresponseheader_route
        uri: https://example.org
        filters:
        - RemoveResponseHeader=X-Response-Foo

这将删除X-Response-Foo标头。spring-doc.cadn.net.cn

要删除任何类型的敏感报头,您应该为可能需要的任何路由配置此过滤器。 此外,您还可以使用spring.cloud.gateway.default-filters并将其应用于所有路由。spring-doc.cadn.net.cn

6.14. 使用RemoveRequestParameter GatewayFilter

RemoveRequestParameter GatewayFilterfactory 采用name参数。 它是要删除的查询参数的名称。 以下示例将RemoveRequestParameter GatewayFilter:spring-doc.cadn.net.cn

例 39.application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: removerequestparameter_route
        uri: https://example.org
        filters:
        - RemoveRequestParameter=red

这将删除red参数。spring-doc.cadn.net.cn

6.15.RequestHeaderSize GatewayFilter

RequestHeaderSize GatewayFilter工厂取maxSizeerrorHeaderName参数。 这maxSizeparameter 是请求标头允许的最大数据大小(包括 key 和 value)。这errorHeaderNameparameter 设置包含错误消息的响应标头的名称,默认情况下为 “errorMessage”。 下面的清单配置了RequestHeaderSize GatewayFilter:spring-doc.cadn.net.cn

例 40.application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: requestheadersize_route
        uri: https://example.org
        filters:
        - RequestHeaderSize=1000B

如果任何请求标头的大小大于 1000 字节,这将发送状态 431。spring-doc.cadn.net.cn

6.16. 使用RewritePath GatewayFilter

RewritePath GatewayFilterFactory 采用路径regexpparameter 和replacement参数。 它使用 Java 正则表达式来灵活地重写请求路径。 下面的清单配置了RewritePath GatewayFilter:spring-doc.cadn.net.cn

例 41.application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: rewritepath_route
        uri: https://example.org
        predicates:
        - Path=/red/**
        filters:
        - RewritePath=/red/?(?<segment>.*), /$\{segment}

对于/red/blue,这会将路径设置为/blue在发出下游请求之前。请注意,由于 YAML 规范,应将其替换为 the。$$\spring-doc.cadn.net.cn

6.17.RewriteLocationResponseHeader GatewayFilter

RewriteLocationResponseHeader GatewayFilterfactory 修改Locationresponse 标头,通常是为了摆脱特定于后端的详细信息。 它需要stripVersionMode,locationHeaderName,hostValueprotocolsRegex参数。 下面的清单配置了RewriteLocationResponseHeader GatewayFilter:spring-doc.cadn.net.cn

例 42.application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: rewritelocationresponseheader_route
        uri: http://example.org
        filters:
        - RewriteLocationResponseHeader=AS_IN_REQUEST, Location, ,

stripVersionModeparameter 的可能值如下:NEVER_STRIP,AS_IN_REQUEST(默认)和ALWAYS_STRIP.spring-doc.cadn.net.cn

hostValue参数(如果提供)用于将host:port响应部分Location页眉。 如果未提供,则Hostrequest 标头。spring-doc.cadn.net.cn

protocolsRegexparameter 必须是有效的正则表达式String,协议名称与之匹配。 如果不匹配,则筛选器不执行任何作。 默认值为http|https|ftp|ftps.spring-doc.cadn.net.cn

6.18. 使用RewriteResponseHeader GatewayFilter

RewriteResponseHeader GatewayFilter工厂取name,regexpreplacement参数。 它使用 Java 正则表达式来灵活地重写响应标头值。 以下示例将RewriteResponseHeader GatewayFilter:spring-doc.cadn.net.cn

例 43.application.yml
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。$\$spring-doc.cadn.net.cn

6.19. 使用SaveSession GatewayFilter

SaveSession GatewayFilterFactory 强制WebSession::save 当使用带有惰性数据存储的 Spring Session 之类的东西时,这特别有用,你需要确保在进行转发调用之前已经保存了会话状态。 以下示例将SaveSession GatewayFilter:spring-doc.cadn.net.cn

例 44.application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: save_session
        uri: https://example.org
        predicates:
        - Path=/foo/**
        filters:
        - SaveSession

如果您将 Spring Security 与 Spring Session 集成,并希望确保已将安全详细信息转发到远程进程,那么这一点至关重要。spring-doc.cadn.net.cn

6.20. 使用SecureHeaders GatewayFilter

SecureHeaders GatewayFilterFactory 根据此博客文章中的建议,向响应中添加许多标头。spring-doc.cadn.net.cn

添加了以下标头(以其默认值显示):spring-doc.cadn.net.cn

要更改默认值,请在spring.cloud.gateway.filter.secure-headersNamespace。 以下属性可用:spring-doc.cadn.net.cn

要禁用默认值,请将spring.cloud.gateway.filter.secure-headers.disable属性。 以下示例显示了如何执行此作:spring-doc.cadn.net.cn

spring.cloud.gateway.filter.secure-headers.disable=x-frame-options,strict-transport-security
需要使用安全标头的小写全名来禁用它..

6.21. 使用SetPath GatewayFilter

SetPath GatewayFilterFactory 采用路径template参数。 它提供了一种简单的方法来作请求路径,方法是允许路径的模板化段。 这使用了 Spring Framework 中的 URI 模板。 允许多个匹配的区段。 以下示例将SetPath GatewayFilter:spring-doc.cadn.net.cn

例 45.application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: setpath_route
        uri: https://example.org
        predicates:
        - Path=/red/{segment}
        filters:
        - SetPath=/{segment}

对于/red/blue,这会将路径设置为/blue在发出下游请求之前。spring-doc.cadn.net.cn

6.22. 使用SetRequestHeader GatewayFilter

SetRequestHeader GatewayFilter工厂取namevalue参数。 下面的清单配置了SetRequestHeader GatewayFilter:spring-doc.cadn.net.cn

例 46.application.yml
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,这是下游服务将接收到的内容。spring-doc.cadn.net.cn

SetRequestHeader知道用于匹配路径或主机的 URI 变量。 URI 变量可以在值中使用,并在运行时扩展。 以下示例将SetRequestHeader GatewayFilter,它使用一个变量:spring-doc.cadn.net.cn

例 47.application.yml
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工厂取namevalue参数。 下面的清单配置了SetResponseHeader GatewayFilter:spring-doc.cadn.net.cn

例 48.application.yml
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,这是网关客户端将接收到的内容。spring-doc.cadn.net.cn

SetResponseHeader知道用于匹配路径或主机的 URI 变量。 URI 变量可以在值中使用,并将在运行时扩展。 以下示例将SetResponseHeader GatewayFilter,它使用一个变量:spring-doc.cadn.net.cn

例 49.application.yml
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 GatewayFilterfactory 接受单个参数status. 它必须是有效的 SpringHttpStatus. 它可能是整数值404或枚举的字符串表示形式:NOT_FOUND. 下面的清单配置了SetStatus GatewayFilter:spring-doc.cadn.net.cn

例 50.application.yml
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。spring-doc.cadn.net.cn

您可以配置SetStatus GatewayFilter以在响应的标头中从代理请求返回原始 HTTP 状态代码。 如果配置了以下属性,则会将标头添加到响应中:spring-doc.cadn.net.cn

例 51.application.yml
spring:
  cloud:
    gateway:
      set-status:
        original-status-header-name: original-http-status

6.25. 使用StripPrefix GatewayFilter

StripPrefix GatewayFilterfactory 接受一个参数parts. 这partsparameter 指示在将请求发送到下游之前要从请求中剥离的 path 中的部分数。 下面的清单配置了StripPrefix GatewayFilter:spring-doc.cadn.net.cn

例 52.application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: nameRoot
        uri: https://nameservice
        predicates:
        - Path=/name/**
        filters:
        - StripPrefix=2

当通过网关向/name/blue/red,将请求发送到nameservice看来nameservice/red.spring-doc.cadn.net.cn

6.26. 重试GatewayFilter

Retry GatewayFilterFactory 支持以下参数:spring-doc.cadn.net.cn

  • retries:应尝试的重试次数。spring-doc.cadn.net.cn

  • statuses:应重试的 HTTP 状态代码,使用org.springframework.http.HttpStatus.spring-doc.cadn.net.cn

  • methods:应重试的 HTTP 方法,使用org.springframework.http.HttpMethod.spring-doc.cadn.net.cn

  • series:要重试的一系列状态码,用org.springframework.http.HttpStatus.Series.spring-doc.cadn.net.cn

  • exceptions:应重试的引发异常的列表。spring-doc.cadn.net.cn

  • backoff:为重试配置的指数回退。 重试在firstBackoff * (factor ^ n)哪里n是迭代。 如果maxBackoff时,应用的最大回退限制为maxBackoff. 如果basedOnPreviousValue为 true,则使用prevBackoff * factor.spring-doc.cadn.net.cn

以下默认值配置为Retryfilter(如果启用):spring-doc.cadn.net.cn

下面的清单配置了 RetryGatewayFilter:spring-doc.cadn.net.cn

例 53.application.yml
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.

简化的 “快捷方式” 表示法可以用单个statusmethod.spring-doc.cadn.net.cn

以下两个示例是等效的:spring-doc.cadn.net.cn

例 54.application.yml
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 GatewayFilterfactory 可以限制请求到达下游服务。 过滤器采用maxSize参数。 这maxSize是一个DataSizetype,因此可以将值定义为一个数字,后跟一个可选的DataUnit后缀,例如 'KB' 或 'MB'。字节的默认值为 'B'。 它是以字节为单位定义的请求的允许大小限制。 下面的清单配置了RequestSize GatewayFilter:spring-doc.cadn.net.cn

例 55.application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: request_size_route
        uri: http://localhost:8080/upload
        predicates:
        - Path=/upload
        filters:
        - name: RequestSize
          args:
            maxSize: 5000000

RequestSize GatewayFilterfactory 将响应状态设置为413 Payload Too Large带有额外的标头errorMessage当请求因大小而被拒绝时。以下示例显示了这样一个errorMessage:spring-doc.cadn.net.cn

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 GatewayFilterFactory 可以将现有的 Host Headers 替换为指定的 VAUE。 过滤器采用host参数。 下面的清单配置了SetRequestHostHeader GatewayFilter:spring-doc.cadn.net.cn

例 56.application.yml
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 GatewayFilterfactory 将 host 标头的值替换为example.org.spring-doc.cadn.net.cn

6.29. 修改请求体GatewayFilter

您可以使用ModifyRequestBodyfilter filter filter 在网关向下游发送请求之前修改请求正文。spring-doc.cadn.net.cn

此过滤器只能使用 Java DSL 进行配置。

下面的清单显示了如何修改请求正文GatewayFilter:spring-doc.cadn.net.cn

@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

您可以使用ModifyResponseBodyfilter 在将响应正文发送回客户端之前对其进行修改。spring-doc.cadn.net.cn

此过滤器只能使用 Java DSL 进行配置。

以下清单显示了如何修改响应正文GatewayFilter:spring-doc.cadn.net.cn

@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-doc.cadn.net.cn

Spring Cloud 网关可以将 OAuth2 访问令牌下游转发到服务 它是代理。要将此功能添加到网关,您需要添加TokenRelayGatewayFilterFactory喜欢这个:spring-doc.cadn.net.cn

App.java
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
    return builder.routes()
            .route("resource", r -> r.path("/resource")
                    .filters(f -> f.tokenRelay())
                    .uri("http://localhost:9000"))
            .build();
}
应用程序.yaml
spring:
  cloud:
    gateway:
      routes:
      - id: resource
        uri: http://localhost:9000
        predicates:
        - Path=/resource
        filters:
        - TokenRelay=

它会(除了登录用户和获取令牌之外) 将身份验证令牌下游传递给服务(在本例中为/resource).spring-doc.cadn.net.cn

要为 Spring Cloud 网关启用此功能,请添加以下依赖项spring-doc.cadn.net.cn

它是如何工作的?这 {githubmaster}/src/main/java/org/springframework/cloud/gateway/security/TokenRelayGatewayFilterFactory.java[过滤器] 从当前经过身份验证的用户中提取访问令牌, 并将其放入下游请求的请求标头中。spring-doc.cadn.net.cn

有关完整的工作示例,请参阅此项目spring-doc.cadn.net.cn

一个TokenRelayGatewayFilterFactory仅当正确的spring.security.oauth2.client.*属性,这将触发ReactiveClientRegistrationRepository豆。
的默认实现ReactiveOAuth2AuthorizedClientService使用者TokenRelayGatewayFilterFactory使用内存中数据存储。您需要提供自己的实施ReactiveOAuth2AuthorizedClientService如果您需要更强大的解决方案。

6.32. 使用CacheRequestBody GatewayFilter

在某些情况下需要读取正文。由于请求体流只能读取一次,因此我们需要缓存请求体。 您可以使用CacheRequestBodyfilter 在请求发送到下游之前缓存请求 body 并从 exchange 属性中获取 body。spring-doc.cadn.net.cn

下面的清单显示了如何缓存请求正文GatewayFilter:spring-doc.cadn.net.cn

@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();
}
例 57.application.yml
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.spring-doc.cadn.net.cn

此筛选条件仅适用于 http 请求(包括 https)。

6.33. 使用JsonToGrpc GatewayFilter

JSONToGRPCFilter GatewayFilter Factory 将 JSON 负载转换为 gRPC 请求。spring-doc.cadn.net.cn

过滤器采用以下参数:spring-doc.cadn.net.cn

此文件可以使用protoc指定--descriptor_set_out旗:spring-doc.cadn.net.cn

protoc --proto_path=src/main/resources/proto/ \
--descriptor_set_out=src/main/resources/proto/hello.pb  \
src/main/resources/proto/hello.proto
streaming不支持。

application.yml。spring-doc.cadn.net.cn

@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。spring-doc.cadn.net.cn

默认情况下,它将创建一个NettyChannel使用默认的TrustManagerFactory.但是,此TrustManager可以通过创建GrpcSslConfigurer:spring-doc.cadn.net.cn

@Configuration
public class GRPCLocalConfiguration {
    @Bean
    public GRPCSSLContext sslContext() {
        TrustManager trustManager = trustAllCerts();
        return new GRPCSSLContext(trustManager);
    }
}

6.34. 默认过滤器

要添加过滤器并将其应用于所有路由,您可以使用spring.cloud.gateway.default-filters. 此属性采用筛选器列表。 下面的清单定义了一组默认过滤器:spring-doc.cadn.net.cn

例 58.application.yml
spring:
  cloud:
    gateway:
      default-filters:
      - AddResponseHeader=X-Response-Default-Red, Default-Blue
      - PrefixPath=/httpbin