tulip notes
首页
  • 学习笔记

    • 《Vue》
  • 踩坑日记

    • JavaScript
  • MQ
  • Nginx
  • IdentityServer
  • Redis
  • Linux
  • Java
  • SpringBoot
  • SpringCloud
  • MySql
  • docker
  • 算法与设计模式
  • 踩坑与提升
  • Git
  • GitHub技巧
  • Mac
  • 网络
  • 项目构建合集
  • 一些技巧
  • 面试
  • 一些杂货
  • 友情链接
  • 项目发布
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Star-Lord

希望一天成为大师的学徒
首页
  • 学习笔记

    • 《Vue》
  • 踩坑日记

    • JavaScript
  • MQ
  • Nginx
  • IdentityServer
  • Redis
  • Linux
  • Java
  • SpringBoot
  • SpringCloud
  • MySql
  • docker
  • 算法与设计模式
  • 踩坑与提升
  • Git
  • GitHub技巧
  • Mac
  • 网络
  • 项目构建合集
  • 一些技巧
  • 面试
  • 一些杂货
  • 友情链接
  • 项目发布
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • SCAlibaba-Nacos

  • SCAlibaba-Sentinel

  • 负载均衡与服务调用

  • 服务熔断与降级

  • 服务链路追踪与网关

    • Sleuth(Micrometer)
    • GateWay的相关使用
    • GateWay高级特性之Predicate
    • GateWay之Filter相关
      • 过滤器概念与相关资料
        • 概念
        • 作用
        • 请求过程
        • 资料
      • 快速上手
        • 过滤器类型
        • 单一过滤器示例
        • AddRequestHeader
        • RemoveRequestHeader
        • SetRequestHeader
        • Other
        • 全局过滤器-配置文件
        • 自定义全局过滤器
        • GlobalFilter
        • 过滤器执行顺序
        • 跨域问题解决
  • 分布式实战与细节

  • 其他

  • 《SpringCloud》笔记
  • 服务链路追踪与网关
EffectTang
2024-11-07
目录

GateWay之Filter相关

# GateWay之Filter相关

# 过滤器概念与相关资料

# 概念

SpringMVC里面的的拦截器Interceptor,Servlet的过滤器

“pre”和 “post” 分别会在请求被执行前调用和被执行后调用,用来修改请求和响应信息

# 作用

Spring Cloud Gateway 中的过滤器(Filter)是其核心功能之一,用于在请求转发前后对请求和响应进行处理。过滤器可以用来实现各种功能,如请求头和响应头的修改、请求日志记录、限流、熔断、重试等。

它的作用是对进入网关的请求和微服务返回的响应做处理。注意了,它不仅仅会对请求,还会对微服务返回的响应做处理。

# 请求过程

我们已经知道的是,请求进入网关一定要先做路由,我们会有一个断言工厂,它可以基于我们配置的规则完成请求路由,去判断一下到底应该去哪个微服务。

但是路由之后是不是立即就可以向微服务发出请求了呢?

不是这样子的,因为在网关里面我们还可以给我们的路由配置各种各样的过滤器,这个过滤器会形成一个过滤器链,你的请求一定要经过这些过滤器链,然后才能到达微服务。

# 资料

Spring Cloud Gateway-filter (opens new window)

  • https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gatewayfilter-factories

GateWay-单一过滤器使用讲解-官网 (opens new window)

  • https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gatewayfilter-factories

# 快速上手

# 过滤器类型

GateWay提供了三种不同类型的过滤器:

  • 全局过滤器:gateway出厂默认已有的,直接用即可,主要作用于所有的路由

    不需要在配置文件中配置,作用在所有的路由上,实现GlobalFilter接口即可

  • 单一过滤器:也可以称为网关过滤器,这种过滤器主要是作用于单一路由或者某个路由分组

  • 自定义过滤器:就是单一过滤器提供的功能无法满足你,开发者自行实现的过滤器

下面主要介绍的就是单一过滤器。但因为单一过滤器有很多,因此主要介绍其中几个,其余的还请各位开发者朋友们,到官网自行查阅文档。

  • https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gatewayfilter-factories

# 单一过滤器示例

# AddRequestHeader

对应配置如下:

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

1
2
3
4
5
6
7
8
9

这样一来,对应请求一来,请求头中就会带上X-Request-red, 且值为blue。

This listing adds X-Request-red:blue header to the downstream request’s headers for all matching requests.

AddRequestHeader is aware of the URI variables used to match a path or host. URI variables may be used in the value and are expanded at runtime.

# RemoveRequestHeader

作用:删除请求头中的信息

- id: pay_routh3 #pay_routh3
uri: lb://cloud-payment-service                #匹配后提供服务的路由地址
predicates:
  - Path=/pay/gateway/filter/**              # 断言,路径相匹配的进行路由
filters:
  - AddRequestHeader=X-Request-atguigu1,atguiguValue1  # 请求头kv,若一头含有多参则重写一行设置
  - RemoveRequestHeader=sec-fetch-site      # 删除请求头sec-fetch-sit
1
2
3
4
5
6
7

# SetRequestHeader

当然,还有修改请求头,SetRequestHeader

filters:
            - AddRequestHeader=X-Request-atguigu1,atguiguValue1  # 请求头kv,若一头含有多参则重写一行设置
            - AddRequestHeader=X-Request-atguigu2,atguiguValue2
            - RemoveRequestHeader=sec-fetch-site      # 删除请求头sec-fetch-site
            - SetRequestHeader=sec-fetch-mode, Blue-updatebyzzyy # 将请求头sec-fetch-mode对应的值修改为Blue-updatebyzzyy
1
2
3
4
5

# Other

除了有Request的,还有相应的,比如:ResponseHeader

filters:
  - AddRequestParameter=customerId,9527001 # 新增请求参数Parameter:k ,v
  - RemoveRequestParameter=customerName   # 删除url请求参数customerName,你传递过来也是null
  - AddResponseHeader=X-Response-atguigu, BlueResponse # 新增请求参数X-Response-atguigu并设值为BlueResponse

1
2
3
4
5

上述是添加影响的。

还有设置响应的:

- AddResponseHeader=X-Response-atguigu, BlueResponse # 新增请求参数X-Response-atguigu并设值为BlueResponse
- SetResponseHeader=Date,2099-11-11 # 设置回应头Date值为2099-11-11
1
2

RemoveResponseHeader GatewayFilter Factory

- RemoveResponseHeader=Content-Type # 将默认自带Content-Type回应属性删除
1

还有增加前缀的,PrefixPath GatewayFilter Factory

predicates:
  #- Path=/pay/gateway/filter/**   # 被分拆为: PrefixPath + Path

  - Path=/gateway/filter/**              # 断言,为配合PrefixPath测试过滤,暂时注释掉/pay
filters:
  - AddRequestHeader=X-Request-atguigu1,atguiguValue1  #请求头kv,若一头含有多参则重写一行设置
  - PrefixPath=/pay # http://localhost:9527/pay/gateway/filter

1
2
3
4
5
6
7
8

这样后,它映射的地址就是 path+prefixPath

也就是:/pay/gateway/filter/**

....还有很多,请到官网查看

# 全局过滤器-配置文件

  • default-filters

假设你有多个服务,并希望通过网关对它们进行访问,同时希望对所有请求和响应都添加一些公共的头部信息。你的 application.yml 可能看起来像这样:

spring:
  cloud:
    gateway:
      routes:
        - id: service1_route
          uri: http://localhost:8081
          predicates:
            - Path=/service1/**
        - id: service2_route
          uri: http://localhost:8082
          predicates:
            - Path=/service2/**
      default-filters:
        - AddRequestHeader=Global-Request-Header, Global-Request-Value
        - AddResponseHeader=Global-Response-Header, Global-Response-Value
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

在此配置下,任何发送到 /service1/** 或 /service2/** 的请求都将自动包含 Global-Request-Header: Global-Request-Value 请求头,并且所有从这些服务返回的响应都将包含 Global-Response-Header: Global-Response-Value 响应头。

注意事项

  • 优先级:default-filters 是应用于所有路由的过滤器集合,但如果你在特定路由中定义了相同的过滤器,那么特定路由中的配置将覆盖 default-filters 中的配置。
  • 灵活性:虽然 default-filters 提供了一种快速简便的方式来为所有路由添加过滤器,但在处理更复杂的需求时,可能还需要结合自定义全局过滤器或针对具体路由的过滤器配置。

# 自定义全局过滤器

已经有了default-filters,为什么还需要全局过滤器,因为前置无法处理复杂的逻辑。当然全局过滤器,GateWay也有一些内置的,这里就不展开介绍了。

除了使用内置的全局过滤器外,你还可以创建自己的全局过滤器来满足特定需求。要创建自定义的全局过滤器,你需要实现org.springframework.cloud.gateway.filter.GlobalFilter接口,并且通常还需要实现org.springframework.core.Ordered接口来指定过滤器的执行顺序。

import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Component
public class AuthorizationGlobalFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 获取请求中的参数
        String authParam = exchange.getRequest().getQueryParams().getFirst("authorization");

        // 判断参数是否存在以及是否等于'demand'
        if ("demand".equals(authParam)) {
            // 放行请求
            return chain.filter(exchange);
        } else {
            // 拦截请求并返回403 Forbidden状态码
            exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
            return exchange.getResponse().setComplete();
        }
    }

    @Override
    public int getOrder() {
        // 设置过滤器执行顺序,数值越小优先级越高
        return 0;
    }
}
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

以下是对该接口的介绍:

# GlobalFilter

GlobalFilter接口。这个接口中只有一个方法就叫filter,顾名思义过滤。

而这个方法当中有两个参数,一个参数叫exchange,代表的是请求上下文。这个上下文指的是从你请求进入网关开始,一直到结束为止,整个流程中都可以共享exchange对象。那这个对象里边,你可以拿到请求相关的信息,响应相关的信息,甚至于你也可以往里边存个东西,取个东西都没问题。

第二个参数chain就是过滤器链。这个链条上除了你这个过滤器以外,还有别的过滤器,那它的作用就是放行,什么意思呢?你调用这个过滤器链让它往后走,等于你这里逻辑就处理完了,交给别人处理了。

因此这两个参数,第一个参数的作用是来让我们编写整个过滤器的业务逻辑的,你需要的信息这里面都有。而第二个参数是让我们放行来用的,交给下一个过滤器去处理好。

那处理完了以后,它有一个返回值。这个返回值大家比较陌生,它叫mono,是我们web flux里边的一个API。这个东西你没有见过不要紧

通过实现 GlobalFilter 和 Ordered 接口,并使用 @Component 注解将该类声明为Spring管理的组件,你的自定义过滤器将会自动被Spring Cloud Gateway应用到所有的路由上。

# 过滤器执行顺序

  • 排序先看order值,值越小优先级越高值

  • 一样是defauts优先,然后是局部的路由过滤器,最后是全局的global filter过滤器

配置类中的值,按照从上往下,值从1开始,依次累加

# 跨域问题解决

你也可以直接在配置类中配置 CORS,这种方式更加简洁且易于管理:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;

@Configuration
public class CorsConfig {

    @Bean
    public CorsWebFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        
        // 设置允许的源、方法和头部信息
        config.setAllowCredentials(true);
        config.addAllowedOrigin("http://localhost:8080"); // 根据需要调整为具体的前端地址
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config); // 应用于所有路径

        return new CorsWebFilter(source);
    }
}
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
上次更新: 2025/04/23, 16:23:16
GateWay高级特性之Predicate
聚合项目创建

← GateWay高级特性之Predicate 聚合项目创建→

最近更新
01
面向切面跟自定义注解的结合
05-22
02
时间跟其他数据的序列化
05-19
03
数据加密与安全
05-17
更多文章>
Theme by Vdoing | Copyright © 2023-2025 EffectTang
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式