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.hqwc.cn/news/409906.html

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

相关文章

el-table嵌套两层el-dropdown-menu导致样式错乱

问题&#xff1a; 解决方式&#xff1a; <el-table-column label"操作" fixed"right" width"132" align"center"><template slot-scope"scope"><div v-if"scope.row._index ! 合计"><el-d…

如何给新华网投稿发稿?新华网的媒体发稿方法步骤

现如今&#xff0c;互联网已经成为了人们获取信息的主要途径&#xff0c;各大媒体网站也成为了发布自己作品的首选平台。其中&#xff0c;新华网作为中国最具影响力的新闻媒体之一&#xff0c;其内容覆盖面广、触及人群众多&#xff0c;因此&#xff0c;能够在新华网上发表文章…

Angular系列教程之管道

文章目录 管道的基本概念使用内置管道创建自定义管道总结 在Angular中&#xff0c;管道&#xff08;Pipe&#xff09;是一个非常重要的概念。它们允许我们对数据进行转换、格式化和显示&#xff0c;并且可以轻松地在模板中使用。本篇文章将介绍Angular中的管道概念&#xff0c;…

从0到1:实验室设备借用小程序开发笔记

概论 实验室设备借用小程序&#xff0c;适合各大高校&#xff0c;科技园区&#xff0c;大型企业集团的实验室设备借用流程, 通过数字化的手段进一步提升相关单位设备保障水平&#xff0c;规范实验室和设备管理&#xff0c;用户通过手机小程序扫描设备的二维码&#xff0c;可以…

服务器和电脑有啥区别?

服务器可以说是“高配的电脑”&#xff0c;两者都有CPU、硬盘、电源等基础硬件组成&#xff0c;但服务器和电脑也是有一定区别的&#xff0c;让小编带大家了解一下吧&#xff01; #秋天生活图鉴# 1、稳定性需求不同&#xff1a;服务器是全年无休&#xff0c;需要高稳定性&…

【算法Hot100系列】旋转图像

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学习,不断总结,共同进步,活到老学到老导航 檀越剑指大厂系列:全面总结 jav…

东北编程语言???

在GitHub闲逛&#xff0c;偶然发现了东北编程语言&#xff1a; 东北编程语言是由Zhanyong Wan创造的&#xff0c;它使用东北方言词汇作为基本关键字。这种编程语言的特点是简单易懂&#xff0c;适合小学文化程度的人学习&#xff0c;并且易于阅读、编写和记忆。它的语法与其他编…

C#中的反射(Reflection)使用经典案例

文章目录 1. 动态加载和调用类的方法2. 记录用户修改行为3. 调用私有构造函数4. 泛型类型的动态创建和使用5. 动态类型转换与检查6. 获取和设置私有、受保护成员7. 枚举程序集、模块、类型等信息8. 处理泛型类型参数9. 动态生成代码或动态编译10. 配置驱动的应用程序扩展注意事…

武理多媒体信息共享平台的架构设计与实现

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

JNI笔记

JNI笔记 背景Demo代码JNI.javaMainActivity.javaAndroid.mkApplication.mkcom_stone_javacallc_JNI.hjavacallc.cbuild.gradle 背景 Demo代码 代码结构 JNI.java package com.stone.javacallc;/*** Created by stoneWang* Created on 2024/1/16* java调用C*/ public class …

【动态规划】【记忆化搜索】【C++算法】664. 奇怪的打印机

作者推荐 【矩阵快速幂】封装类及测试用例及样例 本文涉及知识点 动态规划 记忆化搜索 字符串 LeetCode:664 奇怪的打印机 有台奇怪的打印机有以下两个特殊要求&#xff1a; 打印机每次只能打印由 同一个字符 组成的序列。 每次可以在从起始到结束的任意位置打印新字符&am…

MacBook安装Storm与启动

MacBook安装Storm与启动 官方下载地址: https://storm.apache.org/downloads.html 官方下载 apache-storm-1.2.2.tar.gz MacBook Linux安装zookeeper 解压 tar -zxvf apache-storm-1.2.2.tar.gz先启动zookeeper cd zookeeper-3.4.12 ./bin/zkServer.sh start #查看状态 ./…