SpringCloudGateway--过滤器(自定义filter)

目录

一、概览 

二、通过GatewayFilter实现

三、继承AbstractGatewayFilterFactory


一、概览 

       当使用Spring Cloud Gateway构建API网关时,可以利用Spring Cloud Gateway提供的内置过滤器(filter)来实现对请求的处理和响应的处理。过滤器可以在请求被路由之前或之后被执行,它可以用于修改请求和响应内容、记录请求日志、校验请求参数、鉴权等等。如果内置的过滤器不能满足需求,可以自定义过滤器。

        之前博客已经介绍了Spring Cloud Gateway内置过滤器的使用方法和示例,具体可以参考:https://blog.csdn.net/qq_41061437/article/details/128069622

        本篇博客将重点介绍如何编写自定义的过滤器,并将其应用到Spring Cloud Gateway中。将使用Java编程语言,以及Spring Boot和Spring Cloud Gateway框架。将通过一个示例来演示如何实现一个自定义过滤器,讲解自定义过滤器的实现方法、配置方法和使用方法。

二、通过GatewayFilter实现

        SpringCloudGateWay项目参考:SpringCloudGateway--自动路由映射与手动路由映射_雨欲语的博客-CSDN博客

        使用GatewayFilter实现需要implements GatewayFilter和Ordered,首先在gateway项目中新建MyOneGatewayFilter类:

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

import java.net.URI;

@Component
public class MyOneGatewayFilter implements GatewayFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 获取请求路径
        String path = exchange.getRequest().getPath().toString();
        URI uri = exchange.getRequest().getURI();
        System.err.println(String.format("获取到请求路径:%s", uri.toString()));
        // 如果请求路径以“/v1”开头,则截取掉第一个路径段
        if (path.startsWith("/v1")) {
            path = path.substring("/v1".length());
        }

        // 创建新的请求对象,并将新路径设置为请求路径
        ServerHttpRequest newRequest = exchange.getRequest().mutate()
                .path(path)
                .build();

        // 使用新请求对象创建新的ServerWebExchange对象
        ServerWebExchange newExchange = exchange.mutate()
                .request(newRequest)
                .build();
        System.err.println(String.format("获取到新的请求路径:%s", newExchange.getRequest().getURI()));
        // 继续执行过滤器链
        return chain.filter(newExchange);
    }

    @Override
    public int getOrder() {
        return 0;
    }
}

        新建GatewayConfig类,

import com.littledyf.filter.MyOneGatewayFilter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


@Configuration
public class GatewayConfig {

    @Value("${server.port}")
    private String port;

    @Bean
    public RouteLocator customerRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
                .route(r -> r.path("/v1/**")
                        .filters(f -> f.filter(new MyOneGatewayFilter()))
                        .uri("http://localhost:" + port)
                )
                .build();
    }

}

        yml文件使用之前的:

server:
  port: 9999
spring:
  application:
    name: service-gateway
  cloud: # 配置Spring Cloud相关属性
    gateway:
      discovery: # 配置网关发现机制
        locator: # 配置处理机制
          enabled: false # 开启网关自动映射处理逻辑
          lower-case-service-id: true # 开启小写转换
      filter:
        secure-headers:
          disable:
            - strict-transport-security
            - x-download-options
      routes: # 配置网关中的一个完整路由,包括命名,地址,谓词集合(规则),过滤器集合
        - id: service-one # 路由定义的命名,唯一即可。命名规则符合Java中的变量符命名规则
          uri: lb://service-one # 当前路由定义对应的微服务转发地址,lb - 代表loadbalance
          predicates: # 配置谓词集合
            - Path=/service/**
          filters:
            - StripPrefix=1
    nacos:
      username: nacos
      password: nacos
      discovery:
        server-addr: 127.0.0.1
        group: dev
        namespace: dev
        metadata:
          version: v1.0.0

        启动项目访问测试:http://localhost:9999/v1/service/nacos/test

        可以看到如果是以v1开头的,会直接进入到我们自定义的MyOneGatewayFilter过滤器中,如果直接service开头,则直接走内置过滤器。

三、继承AbstractGatewayFilterFactory

        xxxxGatewayFilterFactory是符合内置过滤器原则的,所有已经实现的内置过滤器都是按照这种方式进行的,这里就是仿照内置过滤器编写,编写MyTwoGatewayFilterFactory类:

import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.cloud.gateway.support.GatewayToStringStyler;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.net.URI;
import java.util.Arrays;
import java.util.List;

@Component
public class MyTwoGatewayFilterFactory extends AbstractGatewayFilterFactory<MyTwoGatewayFilterFactory.Config> {
    public MyTwoGatewayFilterFactory() {
        super(MyTwoGatewayFilterFactory.Config.class);
    }

    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList("name");
    }

    @Override
    public GatewayFilter apply(MyTwoGatewayFilterFactory.Config config) {
        return new GatewayFilter() {
            @Override
            public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
                // 获取请求路径
                URI uri = exchange.getRequest().getURI();
                System.err.println(String.format("获取到请求路径:%s", uri));
                //
                System.err.println(String.format("配置属性:%s", config.getName()));
                String path = exchange.getRequest().getPath().toString();
                // 如果请求路径以“/xxx”开头,则截取掉第一个路径段,xxx是配置文件中的name属性
                if (path.startsWith("/" + config.getName())) {
                    path = path.substring(("/" + config.getName()).length());
                }else {
                    throw new IllegalStateException("CustomGatewayFilter is not enabled");
                }

                // 创建新的请求对象,并将新路径设置为请求路径
                ServerHttpRequest newRequest = exchange.getRequest().mutate()
                        .path(path)
                        .build();

                // 使用新请求对象创建新的ServerWebExchange对象
                ServerWebExchange newExchange = exchange.mutate()
                        .request(newRequest)
                        .build();
                System.err.println(String.format("获取到新的请求路径:%s", newExchange.getRequest().getURI()));

                return chain.filter(newExchange);
            }

            @Override
            public String toString() {
                return GatewayToStringStyler.filterToStringCreator(MyTwoGatewayFilterFactory.this).toString();
            }
        };
    }

    public static class Config {
        private String name;

        public Config() {
        }

        public String getName() {
            return this.name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }
}

        在配置文件中加上刚编写的自定义过滤器名:

server:
  port: 9999
spring:
  application:
    name: service-gateway
  cloud: # 配置Spring Cloud相关属性
    gateway:
      discovery: # 配置网关发现机制
        locator: # 配置处理机制
          enabled: false # 开启网关自动映射处理逻辑
          lower-case-service-id: true # 开启小写转换
      filter:
        secure-headers:
          disable:
            - strict-transport-security
            - x-download-options
      routes: # 配置网关中的一个完整路由,包括命名,地址,谓词集合(规则),过滤器集合
        - id: service-one # 路由定义的命名,唯一即可。命名规则符合Java中的变量符命名规则
          uri: lb://service-one # 当前路由定义对应的微服务转发地址,lb - 代表loadbalance
          predicates: # 配置谓词集合
            - Path=/service/**
          filters:
            - StripPrefix=1
            - MyTwo=api
    nacos:
      username: nacos
      password: nacos
      discovery:
        server-addr: 127.0.0.1
        group: dev
        namespace: dev
        metadata:
          version: v1.0.0

        测试:http://localhost:9999/service/api/nacos/test

        如果不包含我们定义的api,则直接报错:

        这只是简单展示了自定义过滤器的功能,实际能实现很多复杂功能。比如进行鉴权、黑白名单过滤等等。

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

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

相关文章

TiDB 企业版全新升级,平凯数据库核心特性全解读

作为 TiDB 企业版的全新升级&#xff0c;平凯数据库一经推出便广受媒体及用户关注。 近日&#xff0c;平凯星辰首席科学家丁岩在“平凯数据库全解读”活动中&#xff0c;首次详细介绍了平凯数据库的核心能力。 本文为丁岩演讲实录全文&#xff0c;为方便阅读&#xff0c;已做部…

物联网AI MicroPython传感器学习 之 QMC5883指南针罗盘传感器

学物联网&#xff0c;来万物简单IoT物联网&#xff01;&#xff01; 一、产品简介 QMC5883是一款表面贴装的集成了信号处理电路的三轴磁性传感器&#xff0c;应用场景主要包括罗盘、导航、无人机、机器人和手持设备等一些高精度的场合。 引脚定义 VCC&#xff1a;3V3&#…

自定义的卷积神经网络模型CNN,对图片进行分类并使用图片进行测试模型-适合入门,从模型到训练再到测试,开源项目

自定义的卷积神经网络模型CNN&#xff0c;对图片进行分类并使用图片进行测试模型-适合入门&#xff0c;从模型到训练再到测试&#xff1a;开源项目 开源项目完整代码及基础教程&#xff1a; https://mbd.pub/o/bread/ZZWclp5x CNN模型&#xff1a; 1.导入必要的库和模块&…

数据结构与算法:使用数组模拟环形队列Java版

文章目录 如何使用数组模拟队列环形队列逻辑分析自己写的听课笔记实现代码部分方法说明 如何使用数组模拟队列 不知道如何使用数组模拟队列的可以看上一篇文章 使用数组模拟队列点击跳转 环形队列逻辑分析 自己写的听课笔记 实现代码 package com.haimeng.queue;import java…

uniapp-自定义表格,右边操作栏固定

uniapp-自定义表格&#xff0c;右边操作栏固定 在网上找了一些&#xff0c;没找到特别合适的&#xff0c;收集了一下其他人的思路&#xff0c;基本都是让左边可以滚动&#xff0c;右边定位&#xff0c;自己也尝试写了一下&#xff0c;有点样式上的小bug&#xff0c;还在尝试修…

多线程锁的升级原理是什么

在 Java 中&#xff0c;锁共有 4 种状态&#xff0c;级别从低到高依次为&#xff1a;无状态锁&#xff0c;偏向锁&#xff0c;轻量级锁和重量级锁状态&#xff0c;这几个状态会随着竞争情况逐渐升级。锁可以升级但不能降级。 多线程锁锁升级过程 如下图所示 多线程锁的升级过程…

在NISQ小型计算机上执行大型并行量子计算的可能性

简介 Steve White提出了密度矩阵重整化群&#xff08;DMRG&#xff09;的基本思想&#xff0c;即纠缠是一种有价值的资源&#xff0c;可以用来精确或近似地描述大量子系统。后来&#xff0c;这一思想被理解为优化矩阵积状态&#xff08;MPS&#xff09;的算法&#xff0c;支持…

Android开发笔记(三)—Activity篇

活动组件Activity 启动和结束生命周期启动模式信息传递Intent显式Intent隐式Intent 向下一个Activity发送数据向上一个Activity返回数据 附加信息利用资源文件配置字符串利用元数据传递配置信息给应用页面注册快捷方式 启动和结束 &#xff08;1&#xff09;从当前页面跳到新页…

[idea]关于idea开发乱码的配置

在JAVA开发中&#xff0c;一般统一设置为UTF-8的编码&#xff0c;包括但不限于开发工具、日志架构、虚拟机、文件编码等。常见配置如下&#xff1a; 1、IDEA工具 在idea64.exe.vmoptions、idea.exe.vmoptions中添加&#xff1a; -Dfile.encodingUTF-8 2、JAVA 运行在window…

python科研绘图:条形图

条形图&#xff08;bar chart&#xff09;是一种以条形或柱状排列数据的图形表示形式&#xff0c;可以显示各项目之间的比较。它通常用于展示不同类别的数据&#xff0c;例如在分类问题中的不同类别、不同产品或不同年份的销售数据等。 条形图中的每个条形代表一个类别或一个数…

区块链与教育:颠覆传统,引领未来

区块链与教育&#xff1a;颠覆传统&#xff0c;引领未来 摘要&#xff1a;本文将探讨区块链技术在教育领域的应用及其潜在影响。通过介绍区块链技术的基本原理、教育领域的现状&#xff0c;以及区块链技术在教育中的实际应用案例&#xff0c;我们将展望一个去中心化、安全可信…

软件测试面试高频30道面试题

如果哪个测试经理在看我的文章&#xff0c;希望对面试者要微笑&#xff0c;不然面试结束&#xff0c;出门之后就一万个草泥马奔腾而过&#xff0c;其实面试者并不是希望你给他们什么&#xff0c;而是一种尊重&#xff0c;平等的谈话&#xff0c;不要高高在上感觉自己超牛逼一样…

【星海出品】VUE(一)

Windows安装nvm控制器 Windows里找都PowerShell。右击点击管理员运行。 1.安装choco Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object System.Net.WebClient).DownloadString(https://chocolatey.org/install.ps1))2.安装NVM choco install nvm 3.查看可…

【HeidiSql_01】python在heidisql当中创建新表的注意事项

python在heidisql当中创建新表的注意事项 假设你已经在python当中弄好了所有的结果&#xff0c;并且保存在df_all这个dataframe当中&#xff0c;然后要将其导入数据库当中并创建一张新的表进行保存。 # 构建数据库连接,将merged_df写回数据库 from sqlalchemy import create_e…

中海达守护电力人员作业安全

近日&#xff0c;中海达为电网某换流站作业人员提供的160余套北斗高精度定位产品顺利完成交付。通过使用北斗高精度定位技术&#xff0c;帮助换流站实现了人员&#xff08;车辆&#xff09;位置实时定位、电子围栏实时预警、远程作业指导等应用效果&#xff0c;用高科技保障电网…

【Linux学习笔记】进程概念(上)

1. 冯诺依曼体系结构2. 操作系统的作用3. 进程 1. 冯诺依曼体系结构 如图&#xff0c;这是一个冯诺依曼体系结构简图 其中这里的存储器指的是内存&#xff01; 用通俗的话来解释这个图&#xff0c;就是数据从输入设备进入&#xff0c;然后进入到存储器&#xff0c;CPU从存储器…

echarts 画散点图, x周,y周在指定位置标志一下

文章目录 echarts 画散点图&#xff0c; x周&#xff0c;y周在指定位置标志一下示例一例子二示例三 echarts 画散点图&#xff0c; x周&#xff0c;y周在指定位置标志一下 示例一 let scatterData {data: [[[-0.2, -0.6],[0.4, 0.3],[0.1, 0.4],[0.3, 0.5],[0.09, 0.1],[0.7,…

没有PDF密码,如何解密文件?

PDF文件有两种密码&#xff0c;一个打开密码、一个限制编辑密码&#xff0c;因为PDF文件设置了密码&#xff0c;那么打开、编辑PDF文件就会受到限制。想要解密&#xff0c;我们需要输入正确的密码&#xff0c;但是有时候我们可能会出现忘记密码的情况&#xff0c;或者网上下载P…

2023年最新版潮乎盲盒源码含搭建教程

后台开发语言&#xff1a;后端 Laravel 框架开发 前端开发框架&#xff1a;uniappvue 环境配置: php7.4 mysql5.6 nginx1.22 redis&#xff08;建议宝塔面板或 lnmp&#xff09; 源码获取请自行百度&#xff1a;一生相随博客 一生相随博客致力于分享全网优质资源&#x…

kotlin中集合操作符

集合操作符 1.总数操作符 any —— 判断集合中 是否有满足条件 的元素&#xff1b; all —— 判断集合中的元素 是否都满足条件&#xff1b; none —— 判断集合中是否 都不满足条件&#xff0c;是则返回true&#xff1b; count —— 查询集合中 满足条件 的 元素个数&#x…
最新文章