GO——gin中间件和路由

中间件

参考:https://learnku.com/articles/66234

  • 结构
    • 中间件是函数
    • 中间件函数被放在调用链上
    • 调用链的末尾是路由path对应的函数
  • 执行过程
    • net/http包调用到gin的serverHTTP
      • 参考:go/pkg/mod/github.com/gin-gonic/gin@v1.7.7/gin.go:506
    • 通过path找到路由对应的处理链,赋值给context
      • 参考:go/pkg/mod/github.com/gin-gonic/gin@v1.7.7/gin.go:553
    • 执行c.next()启动链条
问题:中间件函数中为啥要调用next,不调用,能继续执行完后面的中间件吗

参考:https://blog.dianduidian.com/post/gin-%E4%B8%AD%E9%97%B4%E4%BB%B6next%E6%96%B9%E6%B3%95%E5%8E%9F%E7%90%86%E8%A7%A3%E6%9E%90/

  • 可以
  • 即使中间件没有调用next函数,那么后续中间件和handles也会执行
  • 中间件中调用next函数,会先执行后续中间件,然后回到这个中间件,继续执行next函数之后的代码
    • 参考:/Users/didi/go/pkg/mod/github.com/gin-gonic/gin@v1.7.7/context.go:165
      • 这里的c.index是一个共用的值
      • c.handlers[c.index](c)执行的时候可能会变,所以虽然在中间件中有调用next函数,但是中间价并不会重复执行
  • 提前结束,不能使用return,要使用abort
    • abort:c.index = abortIndex
代码参考
package mainimport ("encoding/json""fmt"
)/****  上下文*/// Context 上下文
type Context struct {Keys    map[string]interface{}handles HandleChainindex   int
}type HandleChain []func(ctx *Context)func (c *Context) Render(resultCode int, data interface{}) {d, _ := json.Marshal(data)fmt.Println("resultCode:", resultCode, " , data:", string(d))
}func (c *Context) Next() {c.index++for c.index < len(c.handles) {c.handles[c.index](c)c.index++}
}func (c *Context) reset() {c.index = -1
}/** 路由*/// router 路由
type router struct {Handlers map[string]HandleChain
}type Group struct {Handles HandleChain
}func (r *router) RegisterRoute(url string, f func(*Context), group Group) () {if r.Handlers == nil {r.Handlers = make(map[string]HandleChain)}r.Handlers[url] = append(r.Handlers[url], group.Handles...)r.Handlers[url] = append(r.Handlers[url], f)
}func (g *Group) Use(f func(*Context)) {g.Handles = append(g.Handles, f)
}func (r *router) Run(url string, c *Context) () {c.handles = r.Handlers[url]c.reset()c.Next()
}/** 业务代码*/// PlusController 加法
func PlusController(c *Context) {a := c.Keys["a"].(int)b := c.Keys["b"].(int)c.Render(200, plus(a, b))
}// plus 加法函数
func plus(a, b int) int {return a + b
}// MultiController 乘法
func MultiController(c *Context) {a := c.Keys["a"].(int)b := c.Keys["b"].(int)c.Render(200, multi(a, b))
}// multi 加法函数
func multi(a, b int) int {return a * b
}/** 主函数*/func main() {r := router{}group1 := Group{Handles: HandleChain{func(ctx *Context) {fmt.Println("testMiddle1")},func(ctx *Context) {ctx.Next()fmt.Println("testMiddle2")},}}group2 := Group{Handles: HandleChain{func(ctx *Context) {fmt.Println("testMiddle3")ctx.Next()fmt.Println("testMiddle4")},}}r.RegisterRoute("*", MultiController,group1)r.RegisterRoute("+", PlusController,group2)fmt.Println("----------")r.Run("*", &Context{Keys: map[string]interface{}{"a": 34, "b": 245}})fmt.Println("----------")r.Run("+", &Context{Keys: map[string]interface{}{"a": 34, "b": 245}})
}

在这里插入图片描述

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

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

相关文章

互联网程序员面试方向有哪些

互联网程序员面试的题目和面试方向非常广泛&#xff0c;主要围绕以下几个主题&#xff1a; 基础知识&#xff1a;包括数据结构、算法、面向对象编程、设计模式、网络协议等。例如&#xff0c;如何实现单例模式&#xff0c;二叉树有哪些遍历方式等。编程语言&#xff1a;如Java…

MacOS系统 安装ZooKeeper 和常见问题解决

安装ZooKeeper 和 常见问题 一、安装和启动二、常见问题和解决2.1 配置文件在哪&#xff1f;2.2 安装路径在哪&#xff1f;2.3 如果不想后台运行zookeeper&#xff0c;用完就关&#xff0c;省资源&#xff0c;可以的&#xff01;2.4 启动时&#xff0c;报错2.4 启动/停止使用 z…

MySQL基础笔记(6)函数

函数&#xff1a;是指一段可以直接被另一段程序调用的程序或者代码~&#xff08;MySQL内置&#xff09; 一.字符串函数 trim不能去除中间的空格~ select concat(jsl,1325): 执行如上的代码&#xff0c;返回字符串"jsl1325"。 select lower(JSL); 执行如上的代码&…

【转】git如何使用.gitignore文件设置忽略文件规则

git如何使用.gitignore文件设置忽略文件规则 目录 一.前言 二.讨论一下.gitignore文件规则 三.具体.gitignore文件写法示例 四.讨论一下.gitignore文件规则的生效优先级 五.其他 一.前言 我们使用git进行版本控制的过程中&#xff0c;会希望一些文件不要进行提交&#xff0c;那…

转盘寿司(100%用例)C卷 (JavaPythonC++Node.jsC语言)

寿司店周年庆,正在举办优惠活动回馈新老客户。 寿司转盘上总共有n盘寿司,prices[i]是第i盘寿司的价格,如果客户选择了第i盘寿司,寿司店免费赠送客户距离,第i盘寿司最近的下一盘寿司i,前提是prices[j]< prices[i],如果没有满足条件的j,则不赠送寿司。 每个价格的寿司都…

【严重】GitLab 以其他用户身份执行 Slack 命令

漏洞描述 GitLab 是由GitLab公司开发的、基于Git的集成软件开发平台。使用 Slack 命令在 Slack 聊天环境中运行常见的 GitLab 操作。 GitLab 受影响版本中&#xff0c;由于配置Slack/Mattermost 集成时&#xff0c;未正确验证用户身份信息&#xff0c;导致攻击者可以使用其他…

深度学习基础知识整理

自动编码器 Auto-encoders是一种人工神经网络&#xff0c;用于学习未标记数据的有效编码。它由两个部分组成&#xff1a;编码器和解码器。编码器将输入数据转换为一种更紧凑的表示形式&#xff0c;而解码器则将该表示形式转换回原始数据。这种方法可以用于降维&#xff0c;去噪…

C++入门案例——通讯录管理系统 控制台项目

前言 C入门案例——通讯录管理系统 & 控制台项目 目录 前言总体概览实体类设计显示页面和退出系统 添加联系人逻辑拆解相关代码 显示联系人逻辑拆解相关代码 根据名字删除联系人逻辑拆解相关代码 根据名字查找联系人逻辑拆解相关代码 修改联系人逻辑拆解相关代码 清空所有…

如何理解单例模式----饿汉式?

饿汉式单例模式是一种单例设计模式的实现方式&#xff0c;它在类加载时就创建并初始化了单例对象&#xff0c;无需延迟加载。这种模式的优点是实现简单且线程安全&#xff0c;因为实例在类加载时就已经创建&#xff0c;不存在多线程竞争创建实例的问题。然而&#xff0c;它的缺…

AcWing.899.编辑距离

给定 n 个长度不超过 1010 的字符串以及 m 次询问&#xff0c;每次询问给出一个字符串和一个操作次数上限。 对于每次询问&#xff0c;请你求出给定的 n 个字符串中有多少个字符串可以在上限操作次数内经过操作变成询问给出的字符串。 每个对字符串进行的单个字符的插入、删除或…

C# 中,接口和抽象类的区别,分别在什么时候使用

在C#中&#xff0c;接口和抽象类都可用于创建可由子类实现和继承的规范。尽管它们有相似之处&#xff0c;但在使用场景和行为上存在显著差异。以下是你需要知道的接口和抽象类的区别以及它们各自的使用场景&#xff1a; 定义与目的&#xff1a; 接口&#xff08;Interface&…

(二)模板templates

首 Django模板层是为动态生成html服务的&#xff0c;非本文重点。前后端分离的设计更为常见&#xff0c;尽量少的涉及Django模板层内容。本文记录Django如何找到一个html文件。 模板文件 在创建一个Django项目project后&#xff0c;目录下会生成一个同名目录和manage.py。创…

鸿蒙ArkTS的起源和简介

theme: lilsnake 1、引言 Mozilla创造了JS&#xff0c;Microsoft创建了TS&#xff0c;Huawei进一步推出了ArkTS。 从最初的基础的逻辑交互能力&#xff0c;到具备类型系统的高效工程开发能力&#xff0c;再到融合声明式UI、多维状态管理等丰富的应用开发能力&#xff0c;共同…

ASP.NET Core列表增删改查

前置要求&#xff1a; 1. vueelement-plus实现前端静态页面 HelloWorld.vue <template><h2>hello界面</h2><div class"tableList"><!-- 搜索框 --><el-row :gutter"20"><el-col :span"8"><!-- 搜…

STM32 GD32 瑞萨 psoc 等单片机 无线wifi蓝牙最佳解决方案

新联鑫威一系列低功耗高性价比sdio wifi/蓝牙combo的模块CYWL6208 , CYWL6312, CYW6209等可以搭配stm32 各种型号例如以下,支持sta/ap/apsta&#xff0c;双模蓝牙的应用&#xff0c;支持rt-thread, freertos, Azure RTOS, Linux, Android系统. 稳定强&#xff0c;功耗低&#x…

Linux系统资源分析手段:CPU,内存,磁盘与网络IO的瓶颈定位

前言&#xff1a;性能分析手段的应用场景 用于优化&#xff1a; 在程序编码完成后&#xff0c;我们通常要对自己编写的工具进行功能测试与性能分析。 用于监控&#xff1a; 在观察某个系统的运行情况时&#xff0c;需要观察系统内多个中间件及组件的资源占用情况。 用于测试…

tcpdump常用参数以及wireshark密文解密

tcpdump常用参数以及wireshark密文解密 文章目录 一、tcpdump命令和常用参数二、在wireshark中协议解析 tcpdump常用参数 一、tcpdump命令和常用参数 tcpdump常用命令&#xff1a;tcpdump -i eth0 src host 11.6.224.1 and udp port 161 -s 0 -w 161.pcap &#xff08;161为sn…

C盘满了,我用什么思路清理?

20240115 上周六同事传了一个很大的虚拟机给我&#xff0c;C盘就红了 虽然是飞秋选错了存储文件的路径&#xff0c;但后来忘了&#xff0c;就开始毫无目的删除文件&#xff0c;过程中会有没有权限删除的&#xff0c;这样还是没有改善。 咨询了公司IT技术人员&#xff0c; 告…

leetcode2376. 统计特殊整数

Problem: 2376. 统计特殊整数 文章目录 题目思路Code 题目 如果一个正整数每一个数位都是 互不相同 的&#xff0c;我们称它是 特殊整数 。 给你一个 正 整数 n &#xff0c;请你返回区间 [1, n] 之间特殊整数的数目。 示例 1&#xff1a; 输入&#xff1a;n 20 输出&…

利用python将Excel文件拆分为多个CSV

目录 一、准备工作 二、拆分Excel文件为多个CSV 1、读取Excel文件&#xff1a; 2、确定要拆分的列&#xff1a; 3、创建空的字典来存储CSV文件&#xff1a; 4、循环遍历数据并根据类别拆分&#xff1a; 5、打印或返回CSV文件名字典&#xff1a; 6、保存CSV到特定目录&a…