当前位置: 首页 > news >正文

Spring Cloud Gateway 网关路由

一、路由断言

  • 路由断言就是判断路由转发的规则

二、路由过滤器

1. 路由过滤器可以实现对网关请求的处理,可以使用 Gateway 提供的,也可以自定义过滤器

2. 路由过滤器 GatewayFilter(默认不生效,只有配置到路由后才会生效):

  • 只对一个路由生效,配置到 routes 下,和 predicates 同级

  • 对所有路由生效:配置到 default-filters

3. 全局过滤器 GlobalFilter(所有路由都生效):声明后自动生效

三、网关请求处理流程

业务实战:如果要进行用户校验,应该在网关请求转发之前先完成对用户的校验,判断用户是否有请求权限

  • 网关请求转发:NettyRoutingFilter 的 PRE 阶段

做法:

1. 在 NettyRoutingFilter 之前的过滤器链中自定义过滤器完成登录校验

2. 在自定义过滤器 PRE 阶段完成登录校验(POST 阶段请求已经转发了,不符合业务:先登录才能请求)

3. 网关中没有业务逻辑,只是做路由转发,网关进行登录校验之后获取用户信息并没有实际作用(除了校验)

4. 网关将请求转发到微服务,微服务需要用户信息!网关需要将用户信息传给微服务

5. 怎么传?:网关将请求转发到微服务,其实就是发起了一次 HTTP 请求,可以将用户信息保存到请求头,微服务从请求头中取出用户信息,且不会对业务造成影响 ✔

6. 微服务之间的调用怎么获取用户信息?:网关只将用户信息传递给了一个微服务(cart-service),但是微服务之间会相互调用(trade-service 调用 cart-service)trade-service 并没有用户信息,cart-service 也不会自动将用户信息传递给调用它的微服务

  • 可以使用将用户信息保存到请求头的方式在微服务之间传递用户信息吗
  • 微服务之间的请求(OpenFeign)和网关与微服务之间(Spring Cloud Gateway 内置的)的请求不同,实现方式有差别

 

四、网关统一实现用户登录校验(基于 JWT)

1. 自定义过滤器并控制过滤器的顺序

  • 路由过滤器GatewayFilter(默认不生效,只有配置到路由后才会生效):

    • 只对一个路由生效,配置到 routes 下,和 predicates 同级

    • 对所有路由生效:配置到 default-filters

  •  全局过滤器 GlobalFilter(所有路由都生效):声明后自动生效

filter 方法解读:

  • 参数 1 ServerWebExchange exchange:网关内部的上下文对象,保存网关内部整个过滤器链的共享数据,如 request、response、session 及 一些自定义的共享属性,所有过滤器都可以从 exchange 中读取 / 存储共享数据

  • 参数 2 GatewayFilterChain chain:过滤器链,当前过滤器执行完之后,通过 chain 调用过滤器链中的下一个过滤器

网关采用的是非阻塞式的编程,利用 Mono 定义回调函数,等之后请求转发回来的返回结果有了再调用回调函数(过滤器中 POST 部分的逻辑),一般不用写回调

e.g 实际开发中遇到的回调:接口调用成功后统计接口调用次数 + 1,就是要等到返回结果是 ok 的再去执行调用次数 + 1 的逻辑!

  • 返回值 Mono<Void>:每个过滤器执行完之后直接返回 Mono

自定义过滤器的优先级比 NettyRoutingFilter 高即可,NettyRoutingFilter 的 order 值是 maxInt,优先级最低

// 1. 实现 GlobalFilter 接口中的 filter 方法
// 2. 实现 Orderd 接口的 getOrder 方法,通过 ORDER 控制过滤器优先级
// 3. 放行(将 exchange 传到下一个过滤器)

2. 在网关实现登录校验

  • 获取请求头

  • 判断请求路径是否需要拦截(有些路径不需要登录也可以查看)

    使用 Spring 提供的 AntPathMatcher 的 match() 方法来校验路径是否匹配指定的路径模式 pathPattern(/search/** 等路径)

private final AntPathMatcher antPathMatcher = newAntPathMatcher();

  • 获取 token

  • 校验并解析 token

  • 拦截未登录用户

    • 设置响应状态码:未登录 401

    • 终止流程

3. 网关传递用户信息给下游微服务

  • 传递

    • 使用上下文对象中修改请求的 API:mutate()

    • 将构造好的新的上下文对象传给下一个过滤器

  • 获取:微服务中的很多业务都需要获取用户信息,将从请求头中获取用户信息的逻辑写到拦截器中,统一获取;可能会有很多个微服务,写拦截器要在所有微服务里都写一遍?=> 写到公共模块 common 其他微服务都引入这个模块(依赖),就都有了拦截器的功能 ✔
    • 定义拦截器

      • 实现 HandlerInterceptor 接口其中的 preHandle() 方法,在 Controller 之前执行

      • 实现 afterCompletion() 方法在 Controller 执行完之后执行,清楚 ThreadLocal 中的用户信息

    • 注册拦截器:定义 SpringMVC 的配置类,实现 WebMvcConfigurer 中的 addInterceptors()

    • 扫描包:common 模块和微服务模块所在包不同,Spring 不会自动扫描到配置类,需要自己配置,实现 Spring 自动装配

    • 保存到 ThreadLocal 中,其他业务从 ThreadLocal 取出用户信息

注意❗网关模块不能使用 / 引用 SpringMVC 相关的类,Spring Cloud Gateway 的底层用的不是 SpringMVC,而是响应式的 webflux

网关项目也引入了 common 模块,但是 common 模块中定义了 SpringMVC 的拦截器,微服务项目需要该拦截器,网关不需要该拦截器,如何次拦截器配置类在有些情况(微服务模块)生效,有些情况(网关)不生效?

解决方法:让 SpringMVC 的配置类根据条件来加载,即判断是否有 SpringMVC(网关和其他微服务项目的差别就是是否有 SpringMVC,可以根据是否有 SpringMVC 中的核心 API DispatcherServlet)

实现:使用 Spring 的条件注解 @ConditionalOnClass(DispatcherServlet.class)

4.  微服务之间的信息传递(OpenFeign 传递用户)

用户信息是从 ThreadLocal 中取的,要先从请求头中获取用户信息才能存到 ThreadLocal 中,而请求头中的用户信息是网关向微服务发起请求时添加的,但是微服务之间的是直接调用的,没有经过网关,而是通过 OpenFeign 的远程调用,如何修改 OpenFeign 发起的请求?

  • OpenFeign 中提供了一个拦截器接口 RequestInterceptor,所有由 OpenFeign 发起的请求(远程调用)都会先调用拦截器处理请求

  • 其中的 RequestTemplate 类中提供了一些方法(如 header())可以让我们修改请求头

五、总结

相关文章:

Spring Cloud Gateway 网关路由

一、路由断言 路由断言就是判断路由转发的规则 二、路由过滤器 1. 路由过滤器可以实现对网关请求的处理&#xff0c;可以使用 Gateway 提供的&#xff0c;也可以自定义过滤器 2. 路由过滤器 GatewayFilter&#xff08;默认不生效&#xff0c;只有配置到路由后才会生效&#x…...

【Spring学习】Spring Data Redis:RedisTemplate、Repository、Cache注解

1&#xff0c;spring-data-redis官网 1&#xff09;特点 提供了对不同Redis客户端的整合&#xff08;Lettuce和Jedis&#xff09;提供了RedisTemplate统一API来操作Redis支持Redis的发布订阅模型支持Redis哨兵和Redis集群支持基于Lettuce的响应式编程支持基于JDK、JSON、字符…...

C语言:内存函数

创作不易&#xff0c;友友们给个三连吧&#xff01;&#xff01; C语言标准库中有这样一些内存函数&#xff0c;让我们一起学习吧&#xff01;&#xff01; 一、memcpy函数的使用和模拟实现 void * memcpy ( void * destination, const void * source, size_t num ); 1.1 使…...

Go+:一种简单而强大的编程语言

Go是一种简单而强大的编程语言&#xff0c;它是在Go语言之上构建的&#xff0c;旨在提供更加强大、灵活和易于使用的编程体验。Go与Go语言共享大部分语法和语义&#xff0c;因此Go开发人员可以很快上手Go&#xff0c;同时也可以使用Go来编写更加简洁和高效的代码。在本文中&…...

【开源】SpringBoot框架开发数字化社区网格管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、开发背景四、系统展示五、核心源码5.1 查询企事业单位5.2 查询流动人口5.3 查询精准扶贫5.4 查询案件5.5 查询人口 六、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpringBootMySQL的数字化社区网格管理系统&#xf…...

Lua可变参数函数

基础规则 lua传入参数给一个function时采用的是“多余部分被忽略&#xff0c;缺少部分有nil补足”的形式&#xff1a; function f(a, b)return a or b endCALL PARAMETERS f(3) a3, bnil f(3, 4) a3, b4 f(3, 4, 5) a3, b4 (5 is discarded) unpack/pack…...

Nginx实战:3-日志按天分割

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 一、方式1&#xff1a;定时任务执行分割脚本 1.分割日志脚本 2.添加定时任务 二、方式2&#xff1a;logrotate配置分割 1.logrotate简单介绍 2.新增切割ngi…...

springmvc中的数据提交方式

一、单个数据提交数据 jsp代码&#xff1a; <h2>1单个数据提交</h2> <form action"${pageContext.request.contextPath}/one.action">name<input name"myname"/><br>age<input name"age"><input type&…...

unity2017 遇到visual studio 2017(社区版) 30日试用期到了

安装unity2017 遇到visual studio 2017 30日试用期到了&#xff0c;网上百度搜了好多方法都没有成功。 最后用了这个方法&#xff1a; 1)启动vs2017&#xff0c;在弹出要登录的窗口之前&#xff0c;迅速的点击工具-》选项-》账户&#xff0c;勾选在添加账户或对账户重新进行身…...

Netty应用(六) 之 异步 Channel

目录 12.Netty异步的相关概念 12.1 异步编程的概念 12.2 方式1&#xff1a;主线程阻塞&#xff0c;等待异步线程完成调用&#xff0c;然后主线程发起请求IO 12.3 方式2&#xff1a;主线程注册异步线程&#xff0c;异步线程去回调发起请求IO 12.4 细节注释 12.5 异步的好处…...

STM32CubeMx+MATLAB Simulink串口输出实验,UART/USART串口测试实验

STM32CubeMxMATLAB Simulink串口输出实验...

【51单片机】串口通信实验(包括波特率如何计算)

目录 串口通信实验通信的基本概念串行通信与并行通信异步通信与同步通信单工、 半双工与全双工通信通信速率 51单片机串口介绍串口介绍串口通信简介串口相关寄存器串口工作方式方式0方式1方式 2 和方式 3 串口的使用方法&#xff08;计算波特率&#xff09; 硬件设计软件设计1、…...

Kafka零拷贝技术与传统数据复制次数比较

读Kafka技术书遇到困惑: "对比传统的数据复制和“零拷贝技术”这两种方案。假设有10个消费者&#xff0c;传统复制方式的数据复制次数是41040次&#xff0c;而“零拷贝技术”只需110 11次&#xff08;一次表示从磁盘复制到页面缓存&#xff0c;另外10次表示10个消费者各自…...

npm ERR! network This is a problem related to network connectivity.

遇到 ETIMEDOUT 错误时&#xff0c;这表明npm尝试连接到npm仓库时超时了&#xff0c;这通常是由网络连接问题引起的。这可能是因为网络不稳定、连接速度慢、或者你的网络配置阻止了对npm仓库的访问。以下是一些解决这个问题的步骤&#xff1a; 1. 检查网络连接 首先&#xff…...

【SQL高频基础题】619.只出现一次的最大数字

题目&#xff1a; MyNumbers 表&#xff1a; ------------------- | Column Name | Type | ------------------- | num | int | ------------------- 该表可能包含重复项&#xff08;换句话说&#xff0c;在SQL中&#xff0c;该表没有主键&#xff09;。 这张表的每…...

STM32F1 - GPIO外设

GPIO 1> 硬件框图2> 工作模式 1> 硬件框图 2> 工作模式 C语言描述 /** * brief Configuration Mode enumeration */typedef enum { GPIO_Mode_AIN 0x0, // Analog Input 模拟输入 GPIO_Mode_IN_FLOATING 0x04, // input floating 浮空输入GPIO_Mode_I…...

新增同步管理、操作日志模块,支持公共链接分享,DataEase开源数据可视化分析平台v2.3.0发布

2024年2月5日&#xff0c;DataEase开源数据可视化分析平台正式发布v2.3.0版本。 这一版本的功能升级包括&#xff1a;新增“同步管理”功能模块&#xff0c;用户可通过此模块&#xff0c;将传统数据库中的数据定时同步到Apache Doris中&#xff0c;让数据分析更快速&#xff1…...

跟着pink老师前端入门教程-day19

一、移动WEB开发之流式布局 1、 移动端基础 1.1 浏览器现状 PC端常见浏览器&#xff1a;360浏览器、谷歌浏览器、火狐浏览器、QQ浏览器、百度浏览器、搜狗浏览器、IE浏览器。 移动端常见浏览器&#xff1a;UC浏览器&#xff0c;QQ浏览器&#xff0c;欧朋浏览器&#xff0…...

ChatGPT学习第一周

&#x1f4d6; 学习目标 掌握ChatGPT基础知识 理解ChatGPT的基本功能和工作原理。认识到ChatGPT在日常生活和业务中的潜在应用。 了解AI和机器学习的基本概念 获取人工智能&#xff08;AI&#xff09;和机器学习&#xff08;ML&#xff09;的初步了解。理解这些技术是如何支撑…...

爬爬爬——今天是浏览器窗口切换和给所选人打钩(自动化)

学习爬虫路还很长&#xff0c;第一阶段花了好多天了&#xff0c;还在底层&#xff0c;虽然不是我专业要学习的语言&#xff0c;和必备的知识&#xff0c;但是我感觉还挺有意思的。加油&#xff0c;这两天把建模和ai也不学了&#xff0c;唉过年了懒了&#xff01; 加油坚持就是…...

Docker 离线安装指南

参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性&#xff0c;不同版本的Docker对内核版本有不同要求。例如&#xff0c;Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本&#xff0c;Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

19c补丁后oracle属主变化,导致不能识别磁盘组

补丁后服务器重启&#xff0c;数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后&#xff0c;存在与用户组权限相关的问题。具体表现为&#xff0c;Oracle 实例的运行用户&#xff08;oracle&#xff09;和集…...

【Oracle APEX开发小技巧12】

有如下需求&#xff1a; 有一个问题反馈页面&#xff0c;要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据&#xff0c;方便管理员及时处理反馈。 我的方法&#xff1a;直接将逻辑写在SQL中&#xff0c;这样可以直接在页面展示 完整代码&#xff1a; SELECTSF.FE…...

django filter 统计数量 按属性去重

在Django中&#xff0c;如果你想要根据某个属性对查询集进行去重并统计数量&#xff0c;你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求&#xff1a; 方法1&#xff1a;使用annotate()和Count 假设你有一个模型Item&#xff0c;并且你想…...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面

代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口&#xff08;适配服务端返回 Token&#xff09; export const login async (code, avatar) > {const res await http…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容

目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法&#xff0c;当前调用一个医疗行业的AI识别算法后返回…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”

2025年#高考 将在近日拉开帷幕&#xff0c;#AI 监考一度冲上热搜。当AI深度融入高考&#xff0c;#时间同步 不再是辅助功能&#xff0c;而是决定AI监考系统成败的“生命线”。 AI亮相2025高考&#xff0c;40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕&#xff0c;江西、…...

如何在网页里填写 PDF 表格?

有时候&#xff0c;你可能希望用户能在你的网站上填写 PDF 表单。然而&#xff0c;这件事并不简单&#xff0c;因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件&#xff0c;但原生并不支持编辑或填写它们。更糟的是&#xff0c;如果你想收集表单数据&#xff…...

招商蛇口 | 执笔CID,启幕低密生活新境

作为中国城市生长的力量&#xff0c;招商蛇口以“美好生活承载者”为使命&#xff0c;深耕全球111座城市&#xff0c;以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子&#xff0c;招商蛇口始终与城市发展同频共振&#xff0c;以建筑诠释对土地与生活的…...