spring cloud gateway内置网关filter

简介

spring cloud gateway中内置了很多的路由过滤工程,这些路由过滤工程允许以某种方式修改请求进来的http请求的内容(请求头,请求体)或返回的http响应。路由过滤器主要作用于需要处理的特定路由。spring cloud gateway内置了很多种类的过滤器,大致可以分为:Header、Paramter、Path、Status、Redirect、Hystrix熔断和限流RateLimiter。spring cloud gateway的路由过滤器的命令也遵循一定的规范,xxxxGatewayFilterFactory

AddRequestHeaderGatewayFilter

该过滤器用于:在请求中添加配置的请求头,使用示例如下:

XML 复制代码
spring:
  application:
    name: sc-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:
        - id: sc-service
          uri: lb://sc-consumer
          predicates:
            - Path=/sc-c/**
          filters:
            - AddRequestHeader=need-trace, true
            - StripPrefix=1
   

RemoveRequestHeaderGatewayFilterFactory

该过滤器用于:在请求中移除配置的请求头,使用示例如下:

XML 复制代码
spring:
  application:
    name: sc-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:
        - id: sc-service
          uri: lb://sc-consumer
          predicates:
            - Path=/sc-c/**
          filters:
            - StripPrefix=1
            - RemoveRequestHeader=x-lw-agent
   

该配置表示移除请求中的请求头:x-lw-agent

AddResponseHeaderGatewayFilterFactory

该过滤器用于:在响应中添加配置的请求头,使用示例如下:

XML 复制代码
spring:
  application:
    name: sc-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:
        - id: sc-service
          uri: lb://sc-consumer
          predicates:
            - Path=/sc-c/**
          filters:
            - StripPrefix=1
            - AddResponseHeader=wtf,1111
   

RemoveResponseHeaderGatewayFilterFactory

该过滤器用于:在响应中移除配置的请求头,使用示例如下:

XML 复制代码
spring:
  application:
    name: sc-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:
        - id: sc-service
          uri: lb://sc-consumer
          predicates:
            - Path=/sc-c/**
          filters:
            - StripPrefix=1
            - RemoveResponseHeader=Date
   

RequestHeaderToRequestUriGatewayFilterFactory

该过滤器用于把请求转到请求头中对应配置的映射地址,比如如下的配置:

XML 复制代码
spring:
  application:
    name: sc-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:
        - id: sc-service
          uri: lb://sc-consumer
          predicates:
            - Path=/sc-c/**
          filters:
            - StripPrefix=1
#            - RemoveResponseHeader=Date
            - RequestHeaderToRequestUri=ddd
   

此时,如果发起如下请求时:

curl -i -H "X-New-Url: http://192.168.56.1:9001" http://192.168.56.1:9000/sc-c/hello/gatewayTest

会把该请求转到http://192.168.56.101:9001上,如果配置其他的过滤器:AddRequestHeaderGatewayFilterFactory可以实现灰度发布、路由分流等功能

HystrixGatewayFilterFactory

该过滤器用于处理spring cloud 的熔断逻辑,配置如下:

XML 复制代码
spring:
  application:
    name: sc-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:
        - id: sc-service
          uri: lb://sc-consumer
          predicates:
            - Path=/sc-c/**
          filters:
            - StripPrefix=1
            - name: Hystrix # Hystrix Filter的名称
              args: # Hystrix配置参数
                name: fallbackcmd #HystrixCommand的名字
                fallbackUri: forward:/fallback #fallback对应的uri

hystrix.command.fallbackcmd.execution.isolation.thread.timeoutInMilliseconds: 5000
   

其中:

fallbackUri配置项配置gateway网关处的熔断逻辑

java 复制代码
    @RequestMapping("/fallback")
    public String fallback() {
        return "Spring Cloud Gateway Fallback!";
    }
XML 复制代码
hystrix.command.fallbackcmd.execution.isolation.thread.timeoutInMilliseconds: 5000

该配置项表示熔断降级的超时时间

tips:使用Hystrix过滤器需要添加熔断组件依赖:

XML 复制代码
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>

Parameter

AddRequestParameterGatewayFilterFactory

该过滤器用于在请求中添加请求参数中,使用示例如下:

XML 复制代码
spring:
  application:
    name: sc-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:
        - id: sc-service
          uri: lb://sc-consumer
          predicates:
            - Path=/sc-c/**
          filters:
            - StripPrefix=1
            - AddRequestParameter=address,123
   

此时在请求时,会添加请求参数address,值时123

RemoveRequestParameterGatewayFilterFactory

移除原始请求请求参数

XML 复制代码
spring:
  application:
    name: sc-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:
        - id: sc-service
          uri: lb://sc-consumer
          predicates:
            - Path=/sc-c/**
          filters:
            - StripPrefix=1
            - RemoveRequestParameter=xxx
   

Path

StripPrefixGatewayFilterFactory

截取部分请求uri,使用示例如下:

XML 复制代码
spring:
  application:
    name: sc-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:
        - id: sc-service
          uri: lb://sc-consumer
          predicates:
            - Path=/sc-c/**
          filters:
            - StripPrefix=1

   

执行请求:/sc-c/hello/gatewayTest会截取第一个路径地址(sc-c),最终的请求uri地址是:/hello/gatewayTest

RewritePathGatewayFilterFactory

通过正则表达式重写原始的请求路径,配置示例:

XML 复制代码
spring:
  application:
    name: sc-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:
        - id: sc-service
          uri: lb://sc-consumer
          predicates:
            - Path=/sc-c/**
          filters:
            - RewritePath=/sc-c/(?<segment>.*), /$\{segment}
   

这里的效果和使用StripPrefix效果一样,不过RewritePath更灵活

PrefixPathGatewayFilterFactory

该过滤器为请求添加路由前缀,和StripPrefix相反,配置示例如下:

XML 复制代码
spring:
  application:
    name: sc-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:
        - id: sc-service
          uri: lb://sc-consumer
          predicates:
            - Path=/sc-c/**
          filters:
            - StripPrefix=1
            - PrefixPath=/hello
   

此时请求:/sc-c/gatewayTest 最终请求的地址是:/hello/gatewayTest

Body

ModifyRequestBodyGatewayFilterFactory

用于在转发请求之前修改原始请求体内容,使用示例如下:

java 复制代码
@Bean
    public RouteLocator routes(RouteLocatorBuilder builder) {
        return builder.routes().route("test11",r -> r.path("/sc-c/**")
                        .filters(f -> f.stripPrefix(1)
                                .modifyRequestBody(String.class,String.class,
                       

当然也可以采用另外一种配置文件的方式实现:

1 在classpath下新增route.txt,配置示例内容如下:

XML 复制代码
[
  {
    "filters": [
      {
        "name": "ModifyRequestBody",
        "args": {
          "inClass": "java.lang.String",
          "outClass": "java.lang.String",
          "rewriteFunction": "#{@testRewriteFunction}"
        }
      },
      {
       "name": "StripPrefix",
        "args": {
           "_genkey_0": "1"
       }
      }
 ],
    "id": "test",
    "order": 0,
"predicates": [
      {
        "args": {
          "pattern": "/sc-c/**"
        },
        "name": "Path"
      }
    ],
      "uri": "lb://sc-consumer"
  }
]

2 增加配置代码保存路由

java 复制代码
@Component
public class RouteService {

    @Autowired
    private RouteDefinitionWriter routeDefinitionWriter;

    @PostConstruct
    public void init() {
        String routeConfig = FileUtil.readString("route.txt", StandardCharsets.UTF_8);
        List<RouteDefinition> list = JSONUtil.toList(routeConfig, RouteDefinition.class);
        for (RouteDefinition routeDefinition : list) {
            routeDefinitionWriter.save(Mono.just(routeDefinition)).subscribe();
        }
    }
}

ModifyResponseBodyGatewayFilterFactory

用于在转发响应之前修改原始响应体内容,使用示例如下:

java 复制代码
@Bean
    public RouteLocator routes(RouteLocatorBuilder builder) {
        return builder.routes().route("test11",r -> r.path("/sc-c/**")
                        .filters(f -> f.stripPrefix(1)
                                .modifyRequestBody(String.class,String.class,
                       (exchange,s) -> Mono.just(s + "test"))
                                .modifyResponseBody(String.class,String.class,(exchange,s) -> {
                                    try {
                                        JSONObject entries = JSONUtil.parseObj(s);
                                        entries.set("appName","yc-music");
                                        return Mono.just(JSONUtil.toJsonStr(entries));
                                       } catch (Exception e) {
                                        return Mono.just(s);
                                    }
                                }))
                        .uri("lb://sc-consumer"))
                .build();

    }

当然也可以使用配置文件实现,

XML 复制代码
[
  {
    "filters": [
      {
        "name": "ModifyRequestBody",
        "args": {
          "inClass": "java.lang.String",
          "outClass": "java.lang.String",
          "rewriteFunction": "#{@testRewriteFunction}"
        }
      },
       {
          "name": "ModifyResponseBody",
          "args": {
            "inClass": "java.lang.String",
            "outClass": "java.lang.String",
            "rewriteFunction": "#{@testResponseBodyRewriteFunction}"
          }
       },
      {
       "name": "StripPrefix",
        "args": {
           "_genkey_0": "1"
       }
      }
    ],
    "id": "test",
    "order": 0,
    "predicates": [
      {
        "args": {
          "pattern": "/sc-c/**"
        },
        "name": "Path"
      }
    ],
    "uri": "lb://sc-consumer"
  }
]

代码配置:

java 复制代码
@Component
public class RouteService {

    @Autowired
    private RouteDefinitionWriter routeDefinitionWriter;

    @PostConstruct
    public void init() {
        String routeConfig = FileUtil.readString("route.txt", StandardCharsets.UTF_8);
        List<RouteDefinition> list = JSONUtil.toList(routeConfig, RouteDefinition.class);
        for (RouteDefinition routeDefinition : list) {
            routeDefinitionWriter.save(Mono.just(routeDefinition)).subscribe();
        }
    }
}

组件代码:

java 复制代码
@Component
public class TestRewriteFunction implements RewriteFunction<String, String> {

    @Override
    public Publisher<String> apply(ServerWebExchange serverWebExchange, String s) {
        return Mono.just(s);
    }
}


@Component
public class TestResponseBodyRewriteFunction implements RewriteFunction<String,String> {
    @Override
    public Publisher<String> apply(ServerWebExchange serverWebExchange, String s) {
        try {
            JSONObject entries = JSONUtil.parseObj(s);
            entries.set("appName","yc-music");
            return Mono.just(JSONUtil.toJsonStr(entries));
        } catch (Exception e) {
            return Mono.just(s);
        }
    }
}

其他

RetryGatewayFilterFactory

spring cloud gateway的重试组件,可以通过配置对应的条件,满足时可以重试,使用示例如下:

java 复制代码
    @Bean
    public RouteLocator routes(RouteLocatorBuilder builder) {
        return builder.routes().route("test11",r -> r.path("/sc-c/**")
                        .filters(f -> f.stripPrefix(1)
                                .modifyRequestBody(String.class,String.class,
                                                           (exchange,s) -> Mono.just(s + "test"))
                                .retry((retryConfig -> {
                                    retryConfig.setRetries(3);
                                    retryConfig.setMethods(HttpMethod.POST,HttpMethod.GET);
                                    retryConfig.setExceptions(RuntimeException.class);
                                }))
                                .modifyResponseBody(String.class,String.class,(exchange,s) -> {
                                    try {
                                        JSONObject entries = JSONUtil.parseObj(s);
                                        entries.set("appName","yc-music");
                                        return Mono.just(JSONUtil.toJsonStr(entries));
                                    } catch (Exception e) {
                                        return Mono.just(s);
                                    }
                                }))
                                     .uri("lb://sc-consumer"))
                .build();

    }

当然也可以在配置文件中配置使用:

java 复制代码
[
  {
    "filters": [
     {
       "name": "StripPrefix",
        "args": {
           "_genkey_0": "1"
         }
      },
      {
        "name": "ModifyRequestBody",
        "args": {
          "inClass": "java.lang.String",
          "outClass": "java.lang.String",
          "rewriteFunction": "#{@testRewriteFunction}"
        }
      },
      {
        "name":"Retry",
         "args":{
            "retries": 3,
            "methods": ["GET", "POST"]
         }
      },
      {
          "name": "ModifyResponseBody",
          "args": {
            "inClass": "java.lang.String",
            "outClass": "java.lang.String",
            "rewriteFunction": "#{@testResponseBodyRewriteFunction}"
          }
       }
    ],
    "id": "test",
    "order": 0,
    "predicates": [
      {
        "args": {
          "pattern": "/sc-c/**"
        },
        "name": "Path"
      }
    ],
    "uri": "lb://sc-consumer"
  }
]
     
相关推荐
夕除21 小时前
spring boot 8
java·开发语言
呉師傅21 小时前
佳能LBP251dw打印机恢复出厂设置后变成英文菜单没有中文选项如何恢复中文菜单方法
linux·运维·服务器·网络·电脑
humors22121 小时前
免费云服务清单
服务器·网络·数据库·免费·云服务·网站·带宽
陳103021 小时前
Linux:模拟实现进程池
linux·运维·服务器
usdoc文档预览21 小时前
国产化踩坑:Vue3 / React / 小程序如何免插件实现 OFD 及复杂 Office 文档同屏预览
前端·javascript·react.js·小程序·pdf·word·office文件在线预览
王翼鹏21 小时前
claude 配置Luma MCP 图像识别mcp
java·linux·服务器
UXbot21 小时前
评审前2小时完成页面布局:前端AI工具快速出图工作流
前端·人工智能·交互·产品经理·web app·ui设计
minji...21 小时前
Linux 网络基础之传输层TCP(七)确认应答机制,超时重传机制,连接管理机制(三次握手四次挥手),流量控制,滑动窗口,快重传
linux·运维·服务器·网络·网络协议·tcp/ip·http
MacroZheng21 小时前
IDEA + 阿里 Qoder = 王炸!
java·人工智能·后端
qq_49244844621 小时前
Jmeter Transaction Controller(事务控制器) 的 TPS(每秒事务数)严格固定为 1
java·开发语言·jmeter