SpringCloud——网关过滤工厂GatewayFilterFactory
GatewayFilter 工厂
网关过滤器工厂GatewayFilterFactory 允许以某种方式修改传入的HTTP 请求或返回的HTTP 响应。其作用域是某些特定路由。SpringCloudGateway 包括很多种内置的网关过滤器工厂。下面会学习较常用的几种。
AddRequestHeader
AddRequestHeader GatewayFilter 工厂需要一个 name 和 value 参数。下面的例子配置了一个 AddRequestHeader GatewayFilter。
添加请求头
spring:
application:
name: depart-consumer # 微服务名称
cloud:
gateway:
routes:
- id: add_request_header_route
uri: http://localhost:8080
predicates:
- Path=/**
filters:
- AddRequestHeader=X-Request-Color, blue
新建一个服务,端口8080,获取请求头
package com.zjw.controller;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Enumeration;
/**
* @since 2023/11/28 13:41
*/
@RestController
@RequestMapping("/info")
public class ShowInfoController {
@GetMapping("/header")
public String getHeader(HttpServletRequest request){
Enumeration<String> headers = request.getHeaders("X-Request-Color");
StringBuilder sb = new StringBuilder();
while (headers.hasMoreElements()) {
sb.append(headers.nextElement()).append(" ");
}
return "X-Request-Color: " + sb.toString();
}
}

通过api实现增加请求头。
@Configuration
public class GatewayConfig {
/**
* 增加请求头
*/
@Bean
public RouteLocator addRequestHeader(RouteLocatorBuilder builder) {
return builder.routes()
.route("add_request_header_route",
r -> r.path("/**")
.filters(fs -> fs
.addRequestHeader("X-Request-Color", "blue")
.addRequestHeader("X-Request-Color", "red"))
.uri("http://localhost:8080"))
.build();
}
}
AddRequestHeadersIfNotPresent
AddRequestHeadersIfNotPresentGatewayFilter工厂接受一个由冒号分隔的 name 和 value 键值对的集合。下面的例子配置了一个AddRequestHeadersIfNotPresentGatewayFilter。
spring:
application:
name: depart-consumer # 微服务名称
cloud:
gateway:
routes:
- id: add_request_header_route
uri: http://localhost:8080
predicates:
- Path=/**
filters:
- AddRequestHeader=X-Request-Color, blue
- AddRequestHeadersIfNotPresent=X-Request-Color-1:blue,X-Request-Color-2:green
这个列表为所有匹配的请求在下游请求的header信息中添加了两个header信息 X-Request-Color-1:blue 和 X-Request-Color-2:green。这类似于 AddRequestHeader 的工作方式,但与 AddRequestHeader 不同的是,它只在header 信息不存在的情况下才会这样做。否则,客户端请求中的原始值将被发送。
java写法
@Configuration
public class GatewayConfig {
/**
* addRequestHeader增加请求头
*/
@Bean
public RouteLocator addRequestHeadersIfNotPresent(RouteLocatorBuilder builder) {
return builder.routes()
.route("add_request_header_route",
r -> r.path("/**")
.filters(fs -> fs
.addRequestHeadersIfNotPresent("X-Request-Color:blue"))
.uri("http://localhost:8080"))
.build();
}
}
AddRequestParameter
AddRequestParameterGatewayFilterFactory需要一个 name 和 value 参数。下面的例子配置了一个AddRequestParameterGatewayFilter。
spring:
application:
name: depart-consumer # 微服务名称
cloud:
gateway:
routes:
- id: add_request_parameter_route
uri: http://localhost:8080
predicates:
- Path=/**
filters:
- AddRequestParameter=color, blue
- AddRequestParameter=color, red
java实现
@Configuration
public class GatewayConfig {
/**
* addRequestHeader增加请求头
*/
@Bean
public RouteLocator addRequestParameter(RouteLocatorBuilder builder) {
return builder.routes()
.route("add_request_parameter_route",
r -> r.path("/**")
.filters(fs -> fs
.addRequestParameter("color","red"))
.uri("http://localhost:8080"))
.build();
}
}
AddResponseHeader
AddResponseHeader GatewayFilter 工厂需要一个 name 和 value 参数。下面的例子配置了一个 AddResponseHeader GatewayFilter。
spring:
application:
name: depart-consumer # 微服务名称
cloud:
gateway:
routes:
- id: add_response_header_route
uri: http://localhost:8080
predicates:
- Path=/**
filters:
- AddResponseHeader=X-Response-Color, Blue
java实现
@Configuration
public class GatewayConfig {
/**
* addResponseHeader增加响应头
*/
@Bean
public RouteLocator addResponseHeader(RouteLocatorBuilder builder) {
return builder.routes()
.route("add_response_header_route",
r -> r.path("/**")
.filters(fs -> fs
.addResponseHeader("color","red"))
.uri("http://localhost:8080"))
.build();
}
}
CircuitBreaker
断路器,在微服务架构和Spring Cloud中,断路器模式用于防止故障在分布式系统中蔓延,通过在服务出现问题时自动“断开”服务,从而保护系统的其他部分不受影响。
要启用 Spring Cloud CircuitBreaker 过滤器,你需要添加 spring-cloud-starter-circuitbreaker-reactor-resilience4j 依赖。
spring:
application:
name: depart-consumer # 微服务名称
cloud:
gateway:
routes:
- id: circuitbreaker_route
uri: http://localhost:8080
predicates:
- Path=/**
filters:
- name: CircuitBreaker
args:
name: myCircuitBreaker
fallbackUri: forward:/fb
controller
@RestController
public class FallbackController {
@GetMapping("/fb")
public String fallback(){
return "服务暂不可用";
}
}
java实现
@Configuration
public class GatewayConfig {
/**
* addResponseHeader增加响应头
*/
@Bean
public RouteLocator circuitBreaker(RouteLocatorBuilder builder) {
return builder.routes()
.route("circuitbreaker_route",
r -> r.path("/**")
.filters(fs -> fs
.circuitBreaker(config -> {
config.setName("CircuitBreaker");
config.setFallbackUri("forward:/fb");
}))
.uri("http://localhost:8080"))
.build();
}
}
当访问的服务出现问题时,会调用配置的CircuitBreaker断路器。

PrefixPath
PrefixPath GatewayFilter 工厂需要一个 prefix 参数。下面的例子配置了一个 PrefixPath GatewayFilter。
spring:
application:
name: depart-consumer # 微服务名称
cloud:
gateway:
routes:
- id: prefixpath_route
uri: http://localhost:8080
predicates:
- Path=/**
filters:
- PrefixPath=/info
这就把 /info 作为所有匹配请求的路径的前缀。因此,一个到 /hello 的请求会被发送到 /info/hello。
java实现
@Configuration
public class GatewayConfig {
/**
* prefixPath增加路径前缀
*/
@Bean
public RouteLocator prefixpathRoute(RouteLocatorBuilder builder) {
return builder.routes()
.route("prefixpathRoute", r -> r.path("/**")
.filters(gatewayFilterSpec -> gatewayFilterSpec
.prefixPath("/info"))
.uri("http://localhost:8080"))
.build();
}
}
StripPrefix
StripPrefixGatewayFilter工厂需要一个参数,即parts。parts参数表示在向下游发送请求之前要从路径中剥离的部分的数量。下面的列表配置了一个StripPrefixGatewayFilter。
spring:
application:
name: depart-consumer # 微服务名称
cloud:
gateway:
routes:
- id: nameRoot
uri: http://localhost:8080
predicates:
- Path=/**
filters:
- StripPrefix=2
当通过网关向 /a/b/info 发出请求时,向localhost:8080发出的请求看起来像 localhost:8080/info。
java实现
@Configuration
public class GatewayConfig {
/**
* stripPrefix去掉路径前缀
*/
@Bean
public RouteLocator stripPrefixRoute(RouteLocatorBuilder builder) {
return builder.routes()
.route("stripPrefixRoute", r -> r.path("/**")
.filters(gatewayFilterSpec -> gatewayFilterSpec
.stripPrefix(2))
.uri("http://localhost:8080"))
.build();
}
}
RewritePath
RewritePath GatewayFilter 工厂接收一个路径 regexp 参数和一个 replacement 参数。这是用Java正则表达式来重写请求路径的一种灵活方式。下面的列表配置了一个 RewritePath GatewayFilter。
spring:
application:
name: depart-consumer # 微服务名称
cloud:
gateway:
routes:
- id: rewritepath_route
uri: http://localhost:8080
predicates:
- Path=/a/**
filters:
- RewritePath=/a, /info
对于请求路径为 /a/header 的情况,在进行下游请求之前将路径设置为 /info/header。
java实现
@Configuration
public class GatewayConfig {
/**
* rewritePath路径替换
*/
@Bean
public RouteLocator rewritePathRoute(RouteLocatorBuilder builder) {
return builder.routes()
.route("stripPrefixRoute", r -> r.path("/**")
.filters(gatewayFilterSpec -> gatewayFilterSpec
.rewritePath("/a", "/info"))
.uri("http://localhost:8080"))
.build();
}
}
Redis RateLimiter
Redis的实现是基于 Stripe 的工作。它需要使用 spring-boot-starter-data-redis-reactive Spring Boot Starter。
使用的算法是 令牌桶算法。
redis-rate-limiter.replenishRate 属性定义了每秒钟允许多少个请求(不算放弃的请求)。这是令牌桶被填充的速度。
redis-rate-limiter.burstCapacity 属性是一个用户在一秒钟内允许的最大请求数(不算放弃的请求)。这是令牌桶可以容纳的令牌数量。将此值设置为零会阻止所有请求。
redis-rate-limiter.requestedTokens 属性是指一个请求要花费多少令牌。这是为每个请求从桶中提取的令牌数量,默认为 1。
spring:
application:
name: depart-consumer # 微服务名称
data:
redis:
host: redis
port: 6379
cloud:
gateway:
routes:
- id: requestratelimiter_route
uri: http://localhost:8080
predicates:
- Path=/**
filters:
- name: RequestRateLimiter
args:
key-resolver: "#{@ipKeyResolver}"
redis-rate-limiter.replenishRate: 2
redis-rate-limiter.burstCapacity: 5
redis-rate-limiter.requestedTokens: 1
java中配置KeyResolver
package com.zjw.config;
import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import reactor.core.publisher.Mono;
/**
* @since 2023/11/28 20:27
*/
@Configuration
public class SpringCloudConfig {
/**
* ip限流
*/
@Bean
public KeyResolver ipKeyResolver(){
return exchange -> {
String hostName = exchange.getRequest().getRemoteAddress().getHostName();
System.out.println("hostName = " + hostName);
return Mono.just(hostName);
};
}
}
如果请求的速率过快,会出现429错误。

Default Filters
在 Spring Cloud Gateway 中,"Default Filters" 指的是那些在网关中默认应用的一组过滤器。Spring Cloud Gateway 是基于 Spring Framework 构建的一个 API 网关,它提供了路由、过滤和转发请求到微服务的功能。Default Filters 是这个网关提供的一些内置的过滤器,它们被用来处理进出网关的请求和响应。这些过滤器的目的是提供一些常用的功能,比如修改请求或响应的头部、添加日志、限流等。
Default Filters 包括但不限于:
- AddRequestHeader Filter: 向请求中添加一个新的头部。
- AddResponseHeader Filter: 向响应中添加一个新的头部。
- RewritePath Filter: 重写请求路径。
- SetPath Filter: 设置请求的路径。
- SetStatus Filter: 设置响应的状态码。
- Retry Filter: 在失败的情况下重试请求。
- RateLimiter Filter: 限制请求的速率。
要添加一个filter并将其应用于所有路由,可以使用 spring.cloud.gateway.default-filters。这个属性需要一个filter的列表。
spring:
application:
name: depart-consumer # 微服务名称
cloud:
gateway:
default-filters:
- name: CircuitBreaker
args:
name: myCircuitBreaker
fallbackUri: forward:/fb
这个过滤器的作用是在微服务调用中提供断路器功能,以确保系统的稳定性和弹性
优先级
对于相同filter工厂,在不同位置设置了不同的值,则优先级为:
- 局部filter的优先级高于默认filter的
- API式的filter优先级高于配置式filter的
自定义过滤器工厂
添加自定义类
package com.zjw.factory;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractNameValueGatewayFilterFactory;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
/**
* 自定义过滤器工厂
* @since 2023/11/28 21:39
*/
@Component
public class AddHeaderGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory {
/**
* 修改请求头,使用方式:
* 在配置中添加
* filters:
* - AddHeader=new-color, red
*/
@Override
public GatewayFilter apply(NameValueConfig config) {
return (exchange, chain) -> {
ServerHttpRequest httpRequest = exchange.getRequest()
.mutate()
.header(config.getName(), config.getValue())
.build();
ServerWebExchange webExchange = exchange.mutate()
.request(httpRequest)
.build();
return chain.filter(webExchange);
};
}
}
配置yml
spring:
application:
name: depart-consumer # 微服务名称
cloud:
gateway:
routes:
- id: customize_filter
uri: http://localhost:8080
predicates:
- Path=/**
filters:
- AddHeader=new-color, red
SpringCloud——网关过滤工厂GatewayFilterFactory的更多相关文章
- Spring Cloud Gateway(十):网关过滤器工厂 GatewayFilterFactory
本文基于 spring cloud gateway 2.0.1 1.GatewayFilterFactory 简介 路由过滤器允许以某种方式修改传入的HTTP请求或传出的HTTP响应. 路径过滤器的范 ...
- 构建SpringCloud网关服务
搭建网关 导入maven包: <!--网关依赖--> <dependency> <groupId>org.springframework.cloud</gro ...
- 六. SpringCloud网关
1. Gateway概述 1.1 Gateway是什么 服务网关还可以用Zuul网关,但是Zuul网关由于一些维护问题,所以这里我们学习Gateway网关,SpringCloud全家桶里有个很重要的组 ...
- 线上SpringCloud网关调用微服务跨机房了,咋整?
1.前言 公司内考虑到服务器资源成本的问题,目前业务上还在进行服务的容器化改造和迁移,计划将容器化后的服务,以及一些中间件(MQ.DB.ES.Redis等)尽量都迁移到其他机房. 那你们为什么不用阿里 ...
- 小D课堂 - 新版本微服务springcloud+Docker教程_6-02 springcloud网关组件zuul
笔记 2.SpringCloud的网关组件zuul基本使用 简介:讲解zuul网关基本使用 1.加入依赖 2.启动类加入注解 @EnableZuulProxy 默认集成断路器 ...
- SpringCloud网关无法加载权限及IP黑名单白名单
启动springcloud服务注册中心base,再启动网关远程调用base的接口读取权限等数据,控制台出现加载null权限ERROR提示.在远程调用处打断点,先进入代理,找到抛出异常的原因是reque ...
- SpringCloud gateway 过滤
如果需要获取一张图片但服务器没有过滤图片请求地址时,每次请求图片都需要携带token等安全验证密钥,可到nacos配置网关(gateway)的security配置,可过滤掉你配置的url(可理解为白名 ...
- SpringCloud网关ZUUL集成consul
最近一直在搞基于springcloud的微服务开发,为了不限定微服务开发语言,服务发现决定采用consul不多说上代码 pom文件 <project xmlns="http://mav ...
- SpringCloud服务过滤filter
一.目录展示 二.application.yml配置文件 三.MyZuulFilter package com.zn.filter; import com.netflix.zuul.ZuulFilte ...
- 搭建springCloud网关zuul
一.pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www ...
随机推荐
- Irwin-Hall 分布/CF1477F 题解
Irwin-Hall 分布 对于 \(n\) 个均匀分布于 \([0,1]\) 的连续随机变量 \(X_1,X_2,\dots,X_n\),其和的随机变量 \(X\) 满足: \[P(X\le x)= ...
- Thor: 统一AI模型网关的革新之选
Thor: 统一AI模型网关的革新之选 项目价值 Thor(雷神托尔)作为一个强大的AI模型管理网关,解决了当前AI领域一个关键痛点:不同AI服务商的API格式各异,集成成本高.Thor通过将各种AI ...
- 【效能提升】上线前漏了SQL脚本,漏加上某个配置项了?
背景 一个版本从开始开发到上线,可能经历10多天,甚至更久. 由于这个过程的时间较长,难免出现某些需要执行的SQL脚本.需要配置的配置项,到了上线前,却被遗漏了,最后导致出现线上问题才发现. 我们团队 ...
- QT5笔记: 19. QFileSystemModel 联动 QListView QTableView QTreeView
Model 指的是数据 View 指的是界面,View不用设置,只需要和Model进行绑定,绑定完成之后就是Model的格式了 例子:*本例子中QListView QTableView QTreeVi ...
- sql 周岁计算
select FLOOR(DATEDIFF(DY, substring(身份证字段,7,4), GETDATE()) / 365.25) age from [表名]
- 3. Nginx 命令行参数 & nginx.conf 配置文件的详细说明(附有截图说明)
3. Nginx 命令行参数 & nginx.conf 配置文件的详细说明(附有截图说明) @ 目录 3. Nginx 命令行参数 & nginx.conf 配置文件的详细说明(附有截 ...
- 第二课 - 输入(按键)控制输出(LED)-设备树
在第一课中学习了如何安装NCS开发环境,以及如何新建一个工程,还有如何构建和下载到开发板.并运行了官方的LED闪烁例程. 设备树 我们继续跟着官方开发者学院的教程来学习第二课的课程.官方课程包含了以下 ...
- CTF-CRYPTO-ECC(2)
CTF-CRYPTO-ECC(2) 椭圆加密 4.BSGS(小步大步法) [HITCTF 2021 ] task.py #Elliptic Curve: y^2 = x^3 + 7 mod N whi ...
- 【Matlab】判断点和多面体位置关系的两种方法实现
分别是向量判别法(算法来自他人论文).体积判别法(code 是我从网上找的). 方法一: 向量判别法 方法来自一会议论文:<判断点与多面体空间位置关系的一个新算法_石露>2008年,知网. ...
- Java多线程运行探幽
事关Training2中Task4,想看看经典的两个进程并行会是什么样子 题目概述 实现简单的生产者-消费者模型: Tray托盘容量为1:托盘满时不能放入,空时不能取货 Producer生产者共需生产 ...