Spring Cloud Gateway根据作用范围划分为:GatewayFilter和GlobalFilter
由filter工作流程点,可以知道filter有着非常重要的作用,在“pre”类型的过滤器可以做参数校验、权限校验、流量监控、日志输出、协议转换等,在“post”类型的过滤器中可以做响应内容、响应头的修改,日志的输出,流量监控等
网关过滤器用于拦截并链式处理Web请求,可以实现横切与应用无关的需求,比如:鉴权、限流、日志输出等
Spring Cloud Gateway同zuul类似,有“pre”和“post”两种方式的filter。客户端的请求先经过“pre”类型的filter,然后将请求转发到具体的业务服务,比如上图中的user-service,收到业务服务的响应之后,再经过“post”类型的filter处理,最后返回响应到客户端。filter从作用范围可分为另外两种,一种是针对于单个路由的gateway filter,它在配置文件中的写法同predict类似;另外一种是针对于所有路由的global gateway filer
过滤器允许以某种方式修改传入的HTTP请求或传出的HTTP响应。过滤器可以限定作用在某些特定请求路径上。可以实现横切与应用无关的需求,比如:安全、访问超时的设置等。修改传入的HTTP请求或传出HTTP响应。Spring Cloud Gateway 包含许多内置的网关过滤器工厂,一共22个。包括头部过滤器、路径过滤器、Hystrix过滤器和重写请求URL的过滤器,还有参数和状态码等其他类型的过滤器。根据过滤器工程的用途来划分,可以分为以下几种:Header、Parameter、Path、Body、Status、Session、Redirect、Retry、RateLimiter 和 Hystrix。 Spring Cloud Gateway包含许多内置的GatewayFilter工厂。
GatewayFilter工厂同上一篇介绍的Predicate工厂类似,都是在配置文件application.yml中配置,遵循了约定大于配置的思想,只需要在配置文件配置GatewayFilter Factory的名称,而不需要写全部的类名,比如AddRequestHeaderGatewayFilterFactory只需要在配置文件中写AddRequestHeader,而不是全部类名。在配置文件中配置的GatewayFilter Factory最终都会相应的过滤器工厂类处理。
1、用于向下游服务 添加 请求头,
2、支持 uri variables
1、name:向下游服务传递请求头的 key
2、value:向下游服务传递请求头的 value
1、方式一、添加一个固定的请求头
spring: cloud: nacos: gateway: routes: - id: product-provider-01 uri: lb://product-provider predicates: - Path=/product/findOne filters: - AddRequestHeader=x-token,xxxxx
表示会向下游服务传递一个 x-token 的请求头,值是 xxxxx
2、配合 uri variables 添加动态请求头
spring: cloud: gateway: routes: - id: product-provider-02 uri: lb://product-provider predicates: - Path=/product/findOne/{productId} filters: - AddRequestHeader=x-token,xxxxx-{productId}
表示会向下游服务传递一个 x-token 的请求头,值是 xxxxx-匹配上的productId的值
用于向下游服务 添加一个请求参数
name:添加的参数 key
value:添加的参数 value,可以支持 Path或Host 中的 uri variables
spring: cloud: gateway: routes: - id: product-provider-01 uri: lb://product-provider predicates: - Path=/product/findOne filters: - AddRequestParameter=username,zhangsan
向下游服务增加一个 username = zhangsan 的请求参数
向下游的响应中增加一个 响应头。
1、name:添加的响应头的 key
2、value:添加的响应头的 value,可以支持 Path或Host 中的 uri variables
spring: cloud: gateway: routes: - id: product-provider-01 uri: lb://product-provider predicates: - Path=/product/findOne filters: - AddResponseHeader=encryption,false
向下游服务响应增加一个 encryption = false 的响应头
移除重复的请求头
1、name:需要移除的重复的响应头,多个以 空格 分隔
2、strategy:重复时,移除的策略,默认是RETAIN_FIRST,即保留第一个头
spring: cloud: gateway: routes: - id: product-provider-01 uri: lb://product-provider predicates: - Path=/product/findOne filters: - DedupeResponseHeader=x-token Access-Control-Allow-Credentials Access-Control-Allow-Origin,RETAIN_FIRST
移除上方指定的重复的响应头,并且保留第一个出现的。
将 fromHeader 参数的值 追加到 toHeader 参数中。
toHeader 存在,那么往配置中 toHeader 对应的 header 中追加 fromHeader对应的值
toHeader 不存在,那么往 header 中增加一个header ,key: 配置中的toHeader的值,value: fromHeader 在header中的值
1、fromHeader:从请求参数中获取header的值
2、toHeader:向header中设置一个 header, key是toheader的值,value 是 fromHeader的值
spring: cloud: gateway: routes: - id: product-provider-01 uri: lb://product-provider predicates: - Path=/product/findOne filters: - MapRequestHeader=from-header,x-token
即会向 request 中增加一个 key 为 x-token 的header ,值为 header 中 from-header 对应的值。(存在多种情况,参考描述)
为匹配到的路由,在转发到下游服务时,增加一个前缀prefix
1、prefix:需要增加的路径前缀
spring: cloud: gateway: routes: - id: product-provider-01 uri: lb://product-provider predicates: - Path=/findOne filters: - PrefixPath=/product
访问 http://网关ip:port/findOne ⇒ 转发到下游服务地址 http://product-provider/product/findOne 增加了一个前缀。
它表示在Spring Cloud Gateway转发请求的时候,保持客户端的Host信息不变,然后将它传递到下游服务器中。
没有参数
spring: cloud: gateway: routes: - id: product-provider-01 uri: lb://product-provider predicates: - Path=/product/findOne filters: - PreserveHostHeader
移除请求头中的参数
1、name:需要移除的请求头
spring: cloud: gateway: routes: - id: product-provider-01 uri: lb://product-provider predicates: - Path=/product/findOne filters: - RemoveRequestHeader=x-token
移除响应头
1、name:需要移除的响应头
spring: cloud: gateway: routes: - id: product-provider-01 uri: lb://product-provider predicates: - Path=/product/findOne filters: - RemoveResponseHeader=x-token
移除请求参数,往下游服务传递时,此参数就没有来
1、name:需要移除的请求参数
spring: cloud: gateway: routes: - id: product-provider-01 uri: lb://product-provider predicates: - Path=/product/findOne filters: - RemoveRequestParameter=password
根据正则表达式,执行路径重写
1、regexp:匹配的正则表达式
2、replacement:需要替换成的字符串
注意:
1、在yml配置中 $ 需要写成 $\
2、路径替换规则是: path.replaceAll(regexp,replacement)
spring: cloud: gateway: routes: - id: product-provider-01 uri: lb://product-provider predicates: - Path=/admin/product/findOne filters: - RewritePath=/admin(?/?.*), $\{segment} # 当访问/admin/product/findOne 将会替换成 /product/findOne
页面上访问 /admin/product/findOne ⇒ 到达下游服务的路径是 /product/findOne
移除路径前缀,比如访问: /admin/aa/bb/cc 实际的下游服务器地址是 /bb/cc 则可以使用这个实现
1、parts:请求的路径按照/分隔后,需要跳过的部分,从1开始。
spring: cloud: gateway: routes: - id: product-provider-01 uri: lb://product-provider predicates: - Path=/admin/product/findOne filters: - StripPrefix=1 # 当访问/admin/product/findOne 将会替换成 /product/findOne
页面上访问 /admin/product/findOne ⇒ 到达下游服务的路径是 /product/findOne
配置请求体的大小,当请求体过大时,将会返回 413 Payload Too Large。
1、maxSize:请求体的大小
spring: cloud: gateway: routes: - id: product-provider-01 uri: lb://product-provider predicates: - Path=/product/findOne filters: - name: RequestSize args: maxSize: 1B
此处需要通过 filters[index].args.maxSize 配置,否则不生效。
修改传递到下游服务 RequestBody 的值,比如我们所有的经过网关的服务,到达下游服务时,都需要将 用户当前的用户名和数据权限传递下去,此时就可以使用这个。
修改原始服务的参数,增加username和roles参数传递到下游服务。
@Configuration public class RouteConfig { @Bean public RouteLocator routes(RouteLocatorBuilder builder) { return builder.routes() .route("product-provider", predicateSpec -> predicateSpec.path("/product/modifyRequestBody") .filters(gatewayFilterSpec -> gatewayFilterSpec.modifyRequestBody(String.class, Map.class, MediaType.APPLICATION_JSON_VALUE, (exchange, s) -> { Mapparams = new HashMap<>(16); params.put("old", s); params.put("username", "v_huan"); params.put("roles", "ROLE_ADMIN"); return Mono.just(params); })).uri("lb://product-provider")).build(); } }
全局过滤器不需要在配置文件中配置,作用在所有的路由上,最终通过 GatewayFilterAdapter 包装成 GatewayFilterChain 可识别的过滤器,它是请求业务以及路由的 URI 转换为真实业务服务请求地址的核心过滤器,不需要配置系统初始化时加载,并作用在每个路由上。
当某个请求被路由匹配时,那么所有的全局过滤器(GlobalFilter)和路由匹配到的 GatewayFilter会组合成一个过滤器链,排序规则是通过 Spring 的 Ordered 来排序。
GlobalFilter有pre和post2个执行阶段,优先级越高 pre 阶段执行越早, post阶段执行越迟。
编写一个全局过滤器需要实现 GlobalFilter 接口
下面这些是Gateway内置的全局过滤器,已经在所有路由生效
Spring Cloud Gateway根据作用范围划分为GatewayFilter和GlobalFilter,二者区别如下:
📢文章下方有交流学习区!一起学习进步!也可以前往官网,加入官方微信交流群💪💪💪
📢首发CSDN博客,创作不易,如果觉得文章不错,可以点赞👍收藏📁评论📒
📢你的支持和鼓励是我创作的动力❗❗❗
Spring Cloud Gateway