Gin的中间件执行流程与用法

 一、背景

        我们在使用Gin框架进行Web开发的时候,基本上都会遇到登录拦截的场景。 例如某些接口必须在登录以后才能访问,根据登录用户的信息以及权限,拿到属于自己的数据, 反之,没登录过则直接拒绝访问。  那么我们怎么做到这些登录拦截呢? 做过Java spring开发或者其它框架开发的同学知道,这种场景一般都是设置一个登录的拦截器,全局统一在拦截器进行登录权限校验处理, 符合登录条件则放行请求到业务函数,否则拒绝访问。 这样可以方便我们做统一管理,不需要每个业务函数再自己重复写一套一模一样的拦截逻辑。

        在Gin当中, 中间件和业务处理函数都是一样的类型,都是一种函数,这个函数签名是这样的 func(c *gin.Context){},Gin的Egine对象就是把这些函数func(c *gin.Context){}放到一个slice切片数组里面, 然后默认按照顺序执行。 只要你的函数func(c *gin.Context){}, 我们都可以把这个函数作为Gin的中间件函数。

       业务函数这个handlers切片数组的最后一个元素, 那么在业务函数前面我们可以增加很多的函数,这些函数我们称为中间件函数.

        我们可以调用c.Next() 执行下一个中间件函数/后续函数, 也可以调用c.Abort()终止后续的中间件执行。

        通过c.Next(), 查看源码我们看到这么一个结构:

        c.Next()就是将这个handlers[函数链数组]往下移动一个元素,也就是执行调用下一个中间件函数。

        每个函数接收到的*Context, 都可以随时结束响应HTTP请求,也可以获取HTTP请求参数,由此做到中间件拦截处理的作用。

二、执行流程图

1、总流程图

        

        如果没有调用Abort()、Next()这些函数,则执行是按照中间件使用的顺序执行。

2、Abort()的使用

        调用Abort(), 终止后续中间件的执行,直接响应HTTP内容。 默认Abort(), 响应状态码是200,并且没有任何payload响应内容。  除了Abort(), 还有基于Abort()演变的几个函数,方便我们更改响应状态码例如403、内容等等。

        

        源测试代码:

package mainimport ("fmt""github.com/gin-gonic/gin""net/http"
)func A(c *gin.Context) {fmt.Println("A1")c.Abort()
}func B(c *gin.Context) {fmt.Println("B1")
}func main() {c := gin.Default()// 使用两个中间件函数, 按照定义的顺序执行 A,Bc.Use(A, B)c.GET("/hello", func(c *gin.Context) {fmt.Println("业务函数")c.JSON(http.StatusOK, gin.H{"message": "hello world",})})c.Run()
}

        运行结果:    运行到A中间件遇到Abort(), 后续的中间件或业务函数也不会被执行 

3、Next()的使用 

源测试代码: 

package mainimport ("fmt""github.com/gin-gonic/gin""net/http"
)func A(c *gin.Context) {fmt.Println("A1")c.Next()fmt.Println("A1-end")
}func B(c *gin.Context) {fmt.Println("B1")
}func main() {c := gin.Default()// 使用两个中间件函数, 按照定义的顺序执行 A,Bc.Use(A, B)c.GET("/hello", func(c *gin.Context) {fmt.Println("业务函数")c.JSON(http.StatusOK, gin.H{"message": "hello world",})})c.Run()
}

运行结果: 

        先运行到A中间件, A调用c.Next()此时继续调用下一个中间件, 所以先打印A1、到B1, 最后到业务函数, 输出"业务函数". 最后业务函数执行完毕,退回上一层B中间件,B中间件执行完毕,回到A.  此时A里面的c.Next()已经全部执行完毕,最后输出A1-end, 最后响应HTTP请求.

        所以如果要想做最后的响应拦截,那么第一个中间件要通过c.Next()的方式,在c.Next()之后添加最终响应逻辑。 例如可以统一更改status状态码、或者添加header、或者删除header等等。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Agent AI 智能体的未来

Agent AI智能体的未来可能会变得更加普遍和智能。以下是一些可能出现的趋势和发展方向: 1、个性化服务: Agent AI智能体可能会变得更加个性化,能够根据用户的偏好和习惯提供定制化的服务和建议。 2、多模态交互: 未来的Agent AI可能会支持更多的多模态交…

【麒麟(Linux)系统远程连接到windows系统并进行文件传输】

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言使用步骤总结 前言 一般来说,windows自带远程桌面,使用的RDP协议,Linux上支持RDP协议的软件很多,常用的是Remmi…

陪丨玩丨系丨统搭建制作流程APP小程序H5多端源码前后端一次性交付,本地授权,无二次费用!可定制开发!

陪丨玩app小程序H5开发,软件搭建,程序制作、系统设计 数据存储是陪玩平台源码的重点,没有数据库,用户的账号信息、平台产生的数据都无法顺利存储和读取,不能让用户拥有完善良好的用户体验。虽然是存放在服务器上&…

python下常用的图像处理工具

在Python中,常用的图像处理工具有很多,以下是一些常见的和推荐的工具: OpenCV:OpenCV(Open Source Computer Vision Library)是最流行的计算机视觉库之一,它包含大量的图像处理函数&#xff0c…

ThreeJs 环境配置及遇到问题的解决方法

一、环境搭建 ThreeJs在实际在实际使用中更多的是结合框架开发例如:vue框架、react框架,在使用时需要配置开发环境,本文使用的是vscode ThreeJs NodeJs vue 1、ThreeJs安装 下载路径:GitHub - mrdoob/three.js: JavaScript…

linux 创建管理员用户并使用生成秘钥登录服务器

一台新的云服务器,初始化登录的是root用户,现需要其他人登录该服务器但肯定不能也使用root权限登录,需要创建新的用户并给该用户生成秘钥并给与管理员的权限,通过ssh免密登录 要在Linux系统上创建新用户并赋予管理员权限(sudo权限…

jbutton 按钮 圆角 渐变色

效果图 没按压时背景渐变色 鼠标按压时背景色改变 下面是可用的源码 package com.beijin.robot.utils; import javax.swing.*; import javax.swing.border.Border; import java.awt.*; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent;public clas…

【python打包成exe文件】

python打包成exe文件 2024-03-05 18:29 第三种方式: 用python打成包文件运行即可 首先安装包: pip install pyinstaller 安装成功后, 在当前的文件夹路径下 运行命令 pyinstaller ***.py 文件 接着会自动打包成一个可执行的 exe文件 ,点击这…

IDEA使用技巧(常用设置、快捷键等)

IDEA使用技巧 一、IDEA常用基本设置设置代码背景颜色/主题/字体Ctrl鼠标滚轮缩放字体大小设置字符编码左右两侧的Project,Structure,Maven等按钮消失新增类似sout,psvm的模版切换某个模块编译的JDK版本 二、常用快捷键CtrlAltT包裹代码Alt回车联想补全Ct…

Android 振动和触感反馈功能失效问题分析

文章目录 一、 可以先通过adb来确定是否有打印Log,查看中相关的按键振动事件是否有效二、 适配按键事件三、延长振动时长 在Android13的项目(MTK平台)中遇到这样一个问题,在设置 - 提示音和振动 - 振动和触感反馈 - 打开按触反馈,但是按键没有…

在VSCode中配置多个版本的Python环境,并设置PYTHONHOME环境变量

在VSCode中配置多个版本的Python环境,并设置PYTHONHOME环境变量,可以通过以下步骤进行: 安装多个版本的Python 首先,你需要在你的计算机上安装多个版本的Python。你可以从Python的官方网站下载不同版本的Python安装包&#xff0…

QT5之lambda

使用lambda需要 配置c11 所以在点.pro文件里面配置添加如下 CONFIG c11 使用到qDebug 打印包含头文件 #include<QDebug> lambda 表达式使用 代替槽如下 #include "mainwidget.h" #include<QPushButton> #include<QDebug> mainWidget::mainWid…

Vue路由的模式和原理

一、hash模式&#xff08;默认&#xff09; 使用URL的hash来模拟一个完整的URL&#xff0c;当URL发生改变时不会向服务器发起请求。# 和其后面的字符称为hash&#xff0c;可通过 window.location.hash 获取。当hash改变会触发&#xff08;包括浏览器的前进、后退&#xff09;会…

Kafka(十二)Streams

目录 Streams1 什么式是流式处理2 流式处理的相关概念2.1 拓扑2.2 时间2.2.1 输入时间2.2.2 输出时间 2.3 状态2.4 流和表2.5 时间窗口2.5.1 测试时间窗口 2.6 处理保证 3 流式处理设计模式3.1 单事件处理3.2 使用本地状态3.3 多阶段处理和重分区3.4 使用外部查找&#xff1a;流…

【哈希】Leetcode 两数之和

题目讲解 1. 两数之和 算法讲解 我们希望让这个数组有序&#xff0c;然后再寻找的时候可以很快的找到是否存在这个target - nums[i]&#xff0c;这里需要返回的是下标&#xff0c;所以需要一个数据结构保存key&#xff1a;nums AND val&#xff1a;index&#xff0c;因此我们…

Qt——置灰窗口

在Qt中&#xff0c;你可以使用QGraphicsEffect来将一个窗口置灰化。同时&#xff0c;你可以通过设置QGraphicsEffect来禁用整个窗口上的所有交互。下面是一个简单的示例代码&#xff0c;演示如何在Qt中将一个窗口置灰并禁用交互&#xff1a; #include <QtWidgets>int ma…

Java设计模式 _结构型模式_桥接模式

一、桥接模式 1、桥接模式 桥接模式&#xff08;Bridge Pattern&#xff09;是一种结构型设计模式。用于把一个类中多个维度的抽象化与实现化解耦&#xff0c;使得二者可以独立变化。 2、实现思路 使用桥接模式&#xff0c;一定要找到这个类中两个变化的维度&#xff1a;如支…

《深入理解mybatis原理》 MyBatis的架构设计以及实例分析

《深入理解mybatis原理》 MyBatis的架构设计以及实例分析 MyBatis是目前非常流行的ORM框架&#xff0c;它的功能很强大&#xff0c;然而其实现却比较简单、优雅。本文主要讲述MyBatis的架构设计思路&#xff0c;并且讨论MyBatis的几个核心部件&#xff0c;然后结合一个select查…

七彩虹(Colorful)隐星P16 2023款笔记本电脑原装出厂Win11系统镜像下载 带建Recovery一键还原功能

七彩虹原厂Windows预装OEM专用系统&#xff0c;恢复出厂开箱状态一模一样 适用型号&#xff1a;隐星P16 23 链接&#xff1a;https://pan.baidu.com/s/1Ig5MQMiC8k4VSuCOZRQHUw?pwdak5l 提取码&#xff1a;ak5l 原厂W11系统自带所有驱动、出厂时自带的主题与专用壁纸、系…

C# 使MessageBox.Show弹出框保持最前

要确保 MessageBox.Show 弹出框保持在最前面&#xff0c;你可以使用 MessageBoxOptions 枚举中的 SetForeground 选项。这将确保消息框置于其他窗口之前。 以下是如何在 C# 中使用 MessageBox.Show 来显示一个保持最前的消息框的示例代码&#xff1a; MessageBox.Show("…