如何在 Spring Cloud Gateway 中创建全局过滤器、局部过滤器和自定义条件过滤器

Spring Cloud Gateway 是一个功能强大的 API 网关,能够处理 HTTP 请求、响应及路由。通过过滤器机制,您可以在请求和响应过程中进行各种处理操作,如记录日志、身份验证、限流等。Spring Cloud Gateway 提供了三种主要类型的过滤器:全局过滤器局部过滤器自定义条件过滤器。本文将详细介绍如何在 Spring Cloud Gateway 中创建和使用这些过滤器。

1. 全局过滤器(Global Filter)

全局过滤器是应用于所有请求的过滤器,无论请求被路由到哪个目标服务,都会先经过这些过滤器。全局过滤器适用于需要对所有请求进行操作的场景,如日志记录、请求限流、身份验证等。

创建全局过滤器的步骤

步骤 1:实现 GlobalFilter 接口

要创建全局过滤器,您需要实现 GlobalFilter 接口,并重写 filter 方法。以下是一个简单的全局过滤器,它记录请求的开始时间,并在请求完成后输出请求的处理时长。

示例代码:全局过滤器
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import reactor.core.publisher.Mono;
import lombok.extern.slf4j.Slf4j;

@Component
@Slf4j
public class MyGlobalFilter implements GlobalFilter {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 记录开始时间
        long startTime = System.currentTimeMillis();
        exchange.getAttributes().put("startTime", startTime);

        // 继续执行后续过滤器
        return chain.filter(exchange).then(Mono.fromRunnable(() -> {
            // 计算并输出请求时长
            long endTime = System.currentTimeMillis();
            long duration = endTime - startTime;
            log.info("Request completed in " + duration + "ms");
        }));
    }
}
步骤 2:设置过滤器的执行顺序(可选)

GlobalFilter 接口继承自 Ordered 接口,您可以通过 getOrder() 方法设置过滤器的执行顺序。返回值越小,优先级越高。

@Override
public int getOrder() {
    return -1;  // 高优先级
}
步骤 3:配置全局过滤器

使用 @Component 注解注册全局过滤器,Spring 会自动将其作为全局过滤器进行管理。


2. 局部过滤器(Local Filter)

局部过滤器是应用于特定路由或请求路径的过滤器。它仅在匹配特定路由或条件时执行,适用于只对某些服务、路径或请求类型进行处理的场景。

创建局部过滤器的步骤

步骤 1:实现 GatewayFilter 接口

局部过滤器需要实现 GatewayFilter 接口。以下是一个简单的局部过滤器,它检查请求的路径并在符合条件时记录日志。

示例代码:局部过滤器
import org.springframework.stereotype.Component;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import lombok.extern.slf4j.Slf4j;

@Component
@Slf4j
public class MyLocalFilter implements GatewayFilter {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 获取请求路径
        String path = exchange.getRequest().getURI().getPath();
        log.info("Request path: " + path);

        // 继续执行后续过滤器
        return chain.filter(exchange);
    }
}
步骤 2:通过 RouteLocator 配置路由

在 Spring Cloud Gateway 中,您可以通过 RouteLocator 或 YAML 配置文件为特定的路由添加局部过滤器。

示例代码:配置局部过滤器
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.RouteLocatorBuilder;

@Configuration
public class GatewayConfig {

    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
                .route("my_route", r -> r
                        .path("/api/**")  // 匹配 /api/** 路径的请求
                        .filters(f -> f.filter(new MyLocalFilter()))  // 应用 MyLocalFilter
                        .uri("http://example.com"))  // 目标服务
                .build();
    }
}

在这个例子中,我们创建了一个名为 my_route 的路由,它只对 /api/** 路径的请求应用 MyLocalFilter 过滤器。

方法二:基于 YAML 配置

如果你使用 YAML 配置文件来配置路由,也可以在 application.yml 文件中指定过滤器。

spring:
  cloud:
    gateway:
      routes:
        - id: example_route
          uri: http://example.com
          predicates:
            - Path=/api/v1/**
          filters:
            - name: MyLocalFilter  # 使用你定义的过滤器

为了通过 YAML 使用自定义过滤器,你需要确保在配置中通过 Spring Bean 名称引用该过滤器。若 MyLocalFilter 被 Spring 管理(通过 @Component),可以直接使用 name 来引用。


3. 自定义条件过滤器(Custom Condition Filter)

自定义条件过滤器是根据特定的条件(如请求的查询参数、请求头或路径等)来动态决定是否执行过滤器。这种过滤器提供了更高的灵活性和复杂的过滤逻辑。

创建自定义条件过滤器的步骤

步骤 1:继承 AbstractGatewayFilterFactory 创建过滤器工厂

Spring Cloud Gateway 提供了 AbstractGatewayFilterFactory 类,允许您创建自定义的过滤器工厂。您可以在工厂中设置过滤器的配置项,并根据条件来执行过滤逻辑。

示例代码:自定义条件过滤器
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.ServerHttpRequest;
import org.springframework.http.HttpStatus;
import reactor.core.publisher.Mono;

import java.util.Arrays;
import java.util.List;

@Component
public class MyGatewayFilterFactory extends AbstractGatewayFilterFactory<MyGatewayFilterFactory.Config> {

    public MyGatewayFilterFactory() {
        super(MyGatewayFilterFactory.Config.class); // 指定配置类
    }

    @Override
    public GatewayFilter apply(MyGatewayFilterFactory.Config config) {
        // 创建实际的过滤器
        return new GatewayFilter() {
            @Override
            public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
                ServerHttpRequest request = exchange.getRequest();
                System.out.println("进入了自定义网关过滤器,status:" + config.getStatus());

                // 检查请求的查询参数
                if (request.getQueryParams().containsKey("atguigu")) {
                    return chain.filter(exchange);  // 继续请求
                } else {
                    exchange.getResponse().setStatusCode(HttpStatus.BAD_REQUEST);  // 返回 400 错误
                    return exchange.getResponse().setComplete();  // 完成响应
                }
            }
        };
    }

    // 配置快捷字段的顺序
    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList("status");  // 配置字段名
    }

    // 配置类,保存过滤器的参数
    public static class Config {
        private String status;  // 配置字段

        public String getStatus() {
            return status;
        }

        public void setStatus(String status) {
            this.status = status;
        }
    }
}
步骤 2:在配置文件中应用自定义过滤器

您可以通过 YAML 或 Java 配置文件指定在哪些路由上应用此自定义条件过滤器,并传递参数。

示例代码:在 application.yml 中配置自定义过滤器
spring:
  cloud:
    gateway:
      routes:
        - id: my_route
          uri: http://example.com
          predicates:
            - Path=/api/**  # 匹配 /api/** 路径的请求
          filters:
            - name: MyGatewayFilterFactory  # 引用自定义的过滤器
              args:
                status: "active"  # 配置 status 参数

4. 过滤器类型比较

特性全局过滤器 (Global Filter)局部过滤器 (Local Filter)自定义条件过滤器 (Custom Condition Filter)
适用范围所有请求特定路由或路径的请求基于特定条件,如请求参数、路径等,动态判断是否执行
使用场景日志记录、全局认证、全局限流等特定服务或路径的处理根据条件(如请求参数、头部等)动态处理请求
配置方式通过实现 GlobalFilter 接口并注册为 Spring Bean通过 RouteLocator 或 YAML 配置路由通过 AbstractGatewayFilterFactory 创建工厂

5. 总结

在 Spring Cloud Gateway 中,您可以根据不同的需求创建三种类型的过滤器:

  • 全局过滤器:适用于需要对所有请求进行统一处理的场

景,例如日志记录、认证和授权。

  • 局部过滤器:适用于特定路由或路径的请求,能够灵活地控制不同服务的请求处理。
  • 自定义条件过滤器:根据请求的特定条件(如查询参数、请求头、路径等)动态决定是否执行过滤器逻辑,提供更高的灵活性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/950304.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2.STM32F407ZGT6-外部中断

参考&#xff1a; 1.正点原子。 前言&#xff1a; MCU最重要的一个领域–中断。总结下嵌套向量和外部中断的概念。达到&#xff1a; 1.NVIC是什么&#xff0c;了解中断的整体管理理念。 2.中断里面最简单的外部中断&#xff0c;怎么配置处理。 3.使用STM32CubeMX配置外部中断的…

基于Elasticsearch8的向量检索实现相似图形搜索

Elasticsearch8版本增加了KNN向量检索&#xff0c;可以基于此功能实现以图搜图功能。 1、首先创建索引&#xff0c;es提供了类型为dense_vector的字段&#xff0c;用于存储向量&#xff0c;其中dims是向量维度&#xff0c;可以不配置&#xff0c;es会根据第一条插入的向量维度…

Element-plus表单总结

表单包含输入框&#xff0c;单选框&#xff0c;下拉选择&#xff0c;多选框等用户输入的组件。输入表单&#xff0c;您可以收集、验证和提交数据。 经典表单 最基础的表单包括各种输入表单项&#xff0c;比如input、select、radio、checkbox等。 在每一个form组件中&#xff0…

cursor vip

https://cursor.jeter.eu.org?pf7f4f3fab0af4119bece19ff4a4360c3 可以直接复制命令使用git bash执行即可 命令&#xff1a; bash <(curl -Lk https://gitee.com/kingparks/cursor-vip/releases/download/latest/ic.sh) f7f4f3fab0af4119bece19ff4a4360c3 等待执行完成后…

创建springboot项目

目录 1、使用 https://start.spring.io/ 创建项目Project 选 mavenLanguage 选 javaSpring Boot 选 3.4.1Project MetadataDependencies 2、阿里云网址 更好用 https://start.aliyun.com/ 1、使用 https://start.spring.io/ 创建项目 跳转 Project 选 maven Language 选 jav…

UDP_TCP

目录 1. 回顾端口号2. UDP协议2.1 理解报头2.2 UDP的特点2.3 UDP的缓冲区及注意事项 3. TCP协议3.1 报头3.2 流量控制2.3 数据发送模式3.4 捎带应答3.5 URG && 紧急指针3.6 PSH3.7 RES 1. 回顾端口号 在 TCP/IP 协议中&#xff0c;用 “源IP”&#xff0c; “源端口号”…

Netron可视化深度学习的模型框架,大大降低了大模型的学习门槛

深度学习是机器学习的一个子领域&#xff0c;灵感来源于人脑的神经网络。深度学习通过多层神经网络自动提取数据中的高级特征&#xff0c;能够处理复杂和大量的数据&#xff0c;尤其在图像、语音、自然语言处理等任务中表现出色。常见的深度学习模型&#xff1a; 卷积神经网络…

Python生成高级圣诞树-代码案例剖析

文章目录 &#x1f47d;发现宝藏 ❄️方块圣诞树&#x1f42c;效果截图&#x1f338;代码-可直接运行&#x1f334;代码解析 ❄️线条圣诞树&#x1f42c;效果截图&#x1f338;代码-可直接运行&#x1f334;代码解析 ❄️豪华圣诞树&#x1f42c;效果截图&#x1f338;代码-可…

Flux“炼丹炉”——fluxgym安装教程

一、介绍 这个炼丹炉目前可以训练除了flux-dev之外的其它模型&#xff0c;只需更改一个配置文件内容即可。重要的是训练时不需要提前进行图片裁剪、打标等前置工作&#xff0c;只需下图的三个步骤即可开始训练。它就是——fluxgym。 fluxgym&#xff1a;用于训练具有低 VRAM &…

【PLL】非线性瞬态性能

频率捕获、跟踪响应&#xff0c;是大信号非线性行为锁相范围内的相位、频率跟踪&#xff0c;不是非线性行为 所以&#xff1a;跟踪&#xff0c;是线性区域&#xff1b;捕获&#xff0c;是大信号、非线性区域 锁定范围&#xff1a;没有周跳&#xff08;cycle-slipping&#xff0…

OpenAI CEO 奥特曼发长文《反思》

OpenAI CEO 奥特曼发长文《反思》 --- 引言&#xff1a;从 ChatGPT 到 AGI 的探索 ChatGPT 诞生仅一个多月&#xff0c;如今我们已经过渡到可以进行复杂推理的下一代模型。新年让人们陷入反思&#xff0c;我想分享一些个人想法&#xff0c;谈谈它迄今为止的发展&#xff0c;…

“AI智慧语言训练系统:让语言学习变得更简单有趣

大家好&#xff0c;我是你们的老朋友&#xff0c;一个热衷于探讨科技与教育结合的产品经理。今天&#xff0c;我想和大家聊聊一个让语言学习变得不再头疼的话题——AI智慧语言训练系统。这个系统可是我们语言学习者的福音&#xff0c;让我们一起来揭开它的神秘面纱吧&#xff0…

一、二极管(应用篇)

1.5普通二极管应用 1.5.1钳位电路 利用二极管的固定的导通电压&#xff0c;在二极管处并联用电器&#xff0c;达到用电器的工作电压相对稳定。如果电源处有尖峰电压&#xff0c;则可以通过二极管导入到5v的电源内&#xff0c;防止此尖峰电压干扰用电器 &#xff0c;起到对电路的…

Android Studio 安装配置(个人笔记)

Android studio安装的前提是必须保证安装了jdk1.8版本以上 一、查看是否安装jdk cmd打开命令行&#xff0c;输入java -version 最后是一个关键点 输入 javac &#xff0c;看看有没有相关信息 没有就下载jdk Android studio安装的前提是必须保证安装了jdk1.8版本以上 可以到…

unity学习14:unity里的C#脚本的几个基本生命周期方法, 脚本次序order等

目录 1 初始的C# 脚本 1.1 初始的C# 脚本 1.2 创建时2个默认的方法 2 常用的几个生命周期方法 2.1 脚本的生命周期 2.1.1 其中FixedUpdate 方法 的时间间隔&#xff0c;是在这设置的 2.2 c#的基本语法别搞混 2.2.1 基本的语法 2.2.2 内置的方法名&#xff0c;要求更严…

node.js|浏览器插件|Open-Multiple-URLs的部署和使用,实现一键打开多个URL的强大工具

前言&#xff1a; 在整理各类资源的时候&#xff0c;可能会面临资源非常多的情况&#xff0c;这个时候我们就需要一款能够一键打开多个URL的浏览器插件了 说简单点&#xff0c;其实&#xff0c;迅雷就是这样的&#xff0c;但是迅雷是基于内置nginx浏览器实现的&#xff0c;并…

HTML 显示器纯色亮点检测工具

HTML 显示器纯色亮点检测工具 相关资源文件已经打包成html等文件&#xff0c;可双击直接运行程序&#xff0c;且文章末尾已附上相关源码&#xff0c;以供大家学习交流&#xff0c;博主主页还有更多Html相关程序案例&#xff0c;秉着开源精神的想法&#xff0c;望大家喜欢&#…

dbeaver导入导出数据库(sql文件形式)

目录 前言dbeaver导出数据库dbeaver导入数据库 前言 有时候我们需要复制一份数据库&#xff0c;可以使用dbeaver简单操作&#xff01; dbeaver导出数据库 选中数据库右键->工具->转储数据库 dbeaver导入数据库 选中数据库右键->工具->执行脚本 mysql 默…

接口测试-postman(使用postman测试接口笔记)

一、设置全局变量 1. 点击右上角设置按钮-》打开管理环境窗口-》选择”全局“-》设置变量名称&#xff0c;初始值和当前值设置一样的&#xff0c;放host放拼接的url&#xff0c;key放鉴权那一串字符&#xff0c;然后保存-》去使用全局变量&#xff0c;用{{变量名称}}形式 二、…

enzymejest TDD与BDD开发实战

一、前端自动化测试需要测什么 1. 函数的执行逻辑&#xff0c;对于给定的输入&#xff0c;输出是否符合预期。 2. 用户行为的响应逻辑。 - 对于单元测试而言&#xff0c;测试粒度较细&#xff0c;需要测试内部状态的变更与相应函数是否成功被调用。 - 对于集成测试而言&a…