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

golang gin框架中创建自定义中间件的2种方式总结 - func(*gin.Context)方式和闭包函数方式定义gin中间件

在gin框架中,我们可以通过2种方式创建自定义中间件:

1. 直接定义一个类型为 func(*gin.Context)的函数或者方法

        这种方式是我们常用的方式,也就是定义一个参数为*gin.Context的函数或者方法。定义的方法就是创建一个 参数类型为 gin.HandlerFunc 【 他的原型定义为 type HandlerFunc func(*Context) 】的中间件,如: func XxxFoo(c *gin.Context) {}

        注意: 虽然这种方式定义的中间件和入参和路由处理函数的定义是一样的, 但是他们的用途和业务处理方式是有区别的, 在中间件中我们可以通过  c.Next() 方法继续后面的请求, 通过 c.Abort()方法终止后续的请求, 而路由处理函数中我们是不会应用这2个方法的。

示例: 下面定义了一个日志记录的中间件, 我们在这个中间件中还启动了一个协程来处理费时的任务,注意gin框架在中间件中开启协程 是使用的上下文是拷贝的当前上下文


func OperLogMiddleware(c *gin.Context) {// 请求操作不做记录if c.Request.Method == http.MethodGet {c.Next() // 继续后续请求return // 退出当前函数}// 创建在 goroutine 中使用ginx.Context对象的的副本cCp := c.Copy()go func() {// 主这里 在中间件中使用 Context对象的拷贝if cCp.Request.Method == "POST" {// do something}}()// 如果异常不为空if err:=c.Err();err!=nil{c.Abort() // 终止后续请求     }else{// 继续后面的请求c.Next()}}

使用方法:  r.Use(OperLogMiddleware)  // 注意这里只需要指定我们定义的中间件函数名称即可。

func main() {r := gin.New()r.Use(OperLogMiddleware)r.GET("/test", func(c *gin.Context) {example := c.MustGet("example").(string)// 打印:"12345"log.Println(example)})// 监听并在 0.0.0.0:8080 上启动服务r.Run(":8080")
}

2. 闭包函数方式定义中间件,即自定义一个函数并将这个函数的返回类型设置为 func(*gin.Context) 即 gin.HandlerFunc

这种方式的优点在于我们可以在使用中间件的时候给这个中间件传递一些自定义的参数, 如我们在不同模块中使用中间件是可以把模块名称传递进去等。定义方式如下:

// 注意这里的函数入参可以随意定义 返回必须是gin.HandlerFunc
func XxxFoo(x1,x2 string) gin.HandlerFunc {
    // 这里直接返回函数func(c *gin.Context)
    return func(c *gin.Context) {
        // gin 中间件的处理逻辑在这里
    }
}

示例: 我们还是上面的示例,改写为闭包函数方式来定义中间件。


// 闭包函数方式定义中间件
// 注意这里的这个闭包函数的入参可以随意,你要怎么定义都可以,但是返回必须是gin.HandlerFunc类型,即func(c *gin.Context)类型
func OperLogClosure(moduleName string) gin.HandlerFunc {// 定义处理函数 gin.HandlerFuncvar handlerFn = func(c *gin.Context) {// 请求操作不做记录if c.Request.Method == http.MethodGet {c.Next() // 继续后续请求return   // 退出当前函数}// 创建在 goroutine 中使用ginx.Context对象的的副本cCp := c.Copy()go func() {// 主这里 在中间件中使用 Context对象的拷贝if cCp.Request.Method == "POST" {// do something}}()// 如果异常不为空if err := c.Err(); err != nil {c.Abort() // 终止后续请求} else {// 继续后面的请求c.Next()}}// 返回这个函数 , 当然我们也可以直接 return 这个函数的定义return handlerFn
}

使用方法:  r.Use(OperLogClosure("system"))  // 注意这里在Use的时候是直接执行我们定义的闭包函数

func main() {r := gin.New()// 注意这里Use的参数 我们在这里直接执行我们定义的闭包函数r.Use(OperLogClosure("system"))r.GET("/test", func(c *gin.Context) {example := c.MustGet("example").(string)// 打印:"12345"log.Println(example)})// 监听并在 0.0.0.0:8080 上启动服务r.Run(":8080")
}

总结:gin框架中的中间件实际上也就是一个类型为 func(c *gin.Context) 的函数或者方法定义即可, 我们可以采用直接定义函数的方式或者采用闭包方式来定义中间件,相比之下,闭包方式拥有更好的灵活性,可以随意给我们的中间件传递初始参数, 而普通方式定义的中间件要传递参数就只能是使用全局的上下文了。 同时我们还需要知道gin框架的中间件中的Abort方法和Next方法的使用,以及如何中断当前请求后继续后续请求等。

相关文章:

golang gin框架中创建自定义中间件的2种方式总结 - func(*gin.Context)方式和闭包函数方式定义gin中间件

在gin框架中,我们可以通过2种方式创建自定义中间件: 1. 直接定义一个类型为 func(*gin.Context)的函数或者方法 这种方式是我们常用的方式,也就是定义一个参数为*gin.Context的函数或者方法。定义的方法就是创建一个 参数类型为 gin.Handler…...

Linux高级编程 8.13 文件IO

一、文件IO 操作系统为了方便用户使用系统功能而对外提供的一组系统函数。称之为 系统调用(unistd.h) 其中有个 文件IO,一般都是对设备文件操作,当然也可以对普通文件进行操作。 这是一个基于Linux内核的没有缓存的IO机制 文件IO特性&…...

【k8s】ubuntu18.04 containerd 手动从1.7.15 换为1.7.20

ubutnu18.04之前手动安装了1.7.15现在下载1.7.20containerd-1.7.20-linux-amd64.tar.gz root@k8s-worker-i58265u:/home/zhangbin# root@k8s-worker-i58265u:/home/zhangbin# https://github.com/containerd/containerd/releases/download/v1.7.20/containerd-1.7.20-linux-am…...

常用浮动方式

目录 一、标准流 二、float浮动 三、 flex浮动 3.1flex组成 3.2 主轴对齐方式 3.3侧轴对齐方式 3.4修改主轴方向 3.5弹性盒子换行 3.6行对齐方式 一、标准流 标签在网页中的默认排布规则 例如: 块元素独占一行、行内元素可以一行显示多个 二、float浮动 让块…...

设计模式反模式:UML常见误用案例分析

文章目录 设计模式反模式:UML常见误用案例分析1. 反模式概述2. 反模式的 UML 图示误用2.1 God Object 反模式2.2 Spaghetti Code 反模式2.3 Golden Hammer 反模式2.4 Poltergeist 反模式 3. 总结 设计模式反模式:UML常见误用案例分析 在软件工程领域&am…...

Python编码系列—Python SQL与NoSQL数据库交互:深入探索与实战应用

🌟🌟 欢迎来到我的技术小筑,一个专为技术探索者打造的交流空间。在这里,我们不仅分享代码的智慧,还探讨技术的深度与广度。无论您是资深开发者还是技术新手,这里都有一片属于您的天空。让我们在知识的海洋中…...

贪心算法---跳跃游戏

题目: 给你一个非负整数数组 nums ,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标,如果可以,返回 true ;否则,返回 false 。 思路…...

利用EditPlus进行Json数据格式化

利用EditPlus进行Json数据格式化 git下载地址:https://github.com/michael-deve/CommonData-EditPlusTools.git (安装过editplus的直接将里面的json.js文件复制走就行) 命令:Cscript.exe /nologo “D:\Program Files (x86)\EditPlus 3\json.js” D:\P…...

xss.function靶场(easy)

文章目录 第一关Ma Spaghet!第二关Jefff第三关Ugandan Knuckles第四关Ricardo Milos第五关Ah Thats Hawt第六关Ligma第七关Mafia第八关Ok, Boomer 网址&#xff1a;https://xss.pwnfunction.com/ 第一关Ma Spaghet! 源码 <!-- Challenge --> <h2 id"spaghet&qu…...

【LLM入门】Let‘s reproduce GPT-2 (124M)【完结,重新回顾一下,伟大!】

文章目录 03:43:05 SECTION 4: results in the morning! GPT-2, GPT-3 repro03:56:21 shoutout to llm.c, equivalent but faster code in raw C/CUDA【太牛了ba】03:59:39 summary, phew, build-nanogpt github repo 03:43:05 SECTION 4: results in the morning! GPT-2, GPT-…...

c语言----取反用什么符号

目录 前言 一、逻辑取反 二、按位取反 三、应用场景 前言 在C编程语言中&#xff0c;取反使用符号!表示逻辑取反&#xff0c;而使用~表示按位取反。 其中&#xff0c;逻辑取反!是将表达式的真值&#xff08;非0值&#xff09;转换为假&#xff08;0&#xff09;&#xff0c…...

【html+css 绚丽Loading】 - 000003 乾坤阴阳轮

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享htmlcss 绚丽Loading&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495…...

【Web】巅峰极客2024 部分题解

目录 EncirclingGame GoldenHornKing php_online admin_Test EncirclingGame 玩赢游戏就行 GoldenHornKing 利用点在传入的app 可以打python内存马 /calc?calc_reqconfig.__init__.__globals__[__builtins__][exec](app.add_api_route("/flag",lambda:__i…...

在AMD GPU上进行Grok-1模型的推理

Inferencing with Grok-1 on AMD GPUs — ROCm Blogs 我们展示了如何通过利用ROCm软件平台&#xff0c;能在AMD MI300X GPU加速器上无缝运行xAI公司的Grok-1模型。 介绍 xAI公司在2023年11月发布了Grok-1模型&#xff0c;允许任何人使用、实验和基于它构建。Grok-1的不同之处…...

在亚马逊云科技上部署开源大模型并利用RAG和LangChain开发生成式AI应用

项目简介&#xff1a; 小李哥将继续每天介绍一个基于亚马逊云科技AWS云计算平台的全球前沿AI技术解决方案&#xff0c;帮助大家快速了解国际上最热门的云计算平台亚马逊云科技AWS AI最佳实践&#xff0c;并应用到自己的日常工作里。 本次介绍的是如何在亚马逊云科技上利用Sag…...

Spring——Bean的生命周期

Bean的生命周期牵扯到Bean的实例化、属性赋值、初始化、销毁 其中Bean的实例化有四种方法、构造器实例化、静态工厂、实例工厂、实现FactoryBean接口 对于Bean的生命周期我们可以在Bean初始化之后、销毁之前对Bean进行控制 两种方法&#xff1a; 一、配置 1、在Bean的对象…...

云计算实训30——自动化运维(ansible)

自动化运维 ansible----自动化运维工具 特点&#xff1a; 部署简单&#xff0c;使用ssh管理 管理端与被管理端不需要启动服务 配置简单、功能强大&#xff0c;扩展性强 一、ansible环境搭建 准备四台机器 安装步骤 mo服务器&#xff1a; #下载epel [rootmo ~]# yum -y i…...

网络性能优化:从问题诊断到解决方案

网络性能优化是确保网络高效、稳定运行的关键过程&#xff0c;它通过改进网络设备、协议和配置&#xff0c;以提高网络吞吐量、降低延迟并提升用户体验。在网络性能优化的全过程中&#xff0c;从问题诊断到解决方案的实施&#xff0c;需要经过一系列详细的步骤和策略。本文将从…...

深度学习10--强化学习

强化学习(增强学习、再励学习、评价学习简称RL)是近年来机器学习领域最热门的方向之一&#xff0c;是实现通用人工智能的重要方法之一。本章将通俗易懂地讲一下强化学习中的两个重要的模型DQN 和DDPG。 马尔可夫决策过程(Markov Decison Process,MDP)包括两个对象&#xff…...

SSA-SVM多变量回归预测|樽海鞘群优化算法-支持向量机|Matalb

目录 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 亮点与优势&#xff1a; 二、实际运行效果&#xff1a; 三、算法介绍&#xff1a; 四、完整程序下载&#xff1a; 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 本代码基于Matlab平台编译&a…...

网络编程(Modbus进阶)

思维导图 Modbus RTU&#xff08;先学一点理论&#xff09; 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议&#xff0c;由 Modicon 公司&#xff08;现施耐德电气&#xff09;于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇&#xff0c;在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下&#xff1a; 【Note】&#xff1a;如果你已经完成安装等操作&#xff0c;可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作&#xff0c;重…...

【kafka】Golang实现分布式Masscan任务调度系统

要求&#xff1a; 输出两个程序&#xff0c;一个命令行程序&#xff08;命令行参数用flag&#xff09;和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽&#xff0c;然后将消息推送到kafka里面。 服务端程序&#xff1a; 从kafka消费者接收…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

拉力测试cuda pytorch 把 4070显卡拉满

import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试&#xff0c;通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小&#xff0c;增大可提高计算复杂度duration: 测试持续时间&#xff08;秒&…...

css3笔记 (1) 自用

outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size&#xff1a;0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格&#xff…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)

参考官方文档&#xff1a;https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java&#xff08;供 Kotlin 使用&#xff09; 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...

在 Spring Boot 项目里,MYSQL中json类型字段使用

前言&#xff1a; 因为程序特殊需求导致&#xff0c;需要mysql数据库存储json类型数据&#xff0c;因此记录一下使用流程 1.java实体中新增字段 private List<User> users 2.增加mybatis-plus注解 TableField(typeHandler FastjsonTypeHandler.class) private Lis…...

MyBatis中关于缓存的理解

MyBatis缓存 MyBatis系统当中默认定义两级缓存&#xff1a;一级缓存、二级缓存 默认情况下&#xff0c;只有一级缓存开启&#xff08;sqlSession级别的缓存&#xff09;二级缓存需要手动开启配置&#xff0c;需要局域namespace级别的缓存 一级缓存&#xff08;本地缓存&#…...

从物理机到云原生:全面解析计算虚拟化技术的演进与应用

前言&#xff1a;我的虚拟化技术探索之旅 我最早接触"虚拟机"的概念是从Java开始的——JVM&#xff08;Java Virtual Machine&#xff09;让"一次编写&#xff0c;到处运行"成为可能。这个软件层面的虚拟化让我着迷&#xff0c;但直到后来接触VMware和Doc…...