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 main

import (
	"encoding/json"
	"fmt"
)

/****  上下文
 */

// Context 上下文
type Context struct {
	Keys    map[string]interface{}
	handles HandleChain
	index   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}})
}

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

FlinkSQL【分组聚合-多维分析-性能调优】应用实例分析

FlinkSQL处理如下实时数据需求&#xff1a; 实时聚合不同 类型/账号/发布时间 的各个指标数据&#xff0c;比如&#xff1a;初始化/初始化后删除/初始化后取消/推送/成功/失败 的指标数据。要求实时产出指标数据&#xff0c;数据源是mysql cdc binlog数据。 代码实例 --SET t…

【.net core】yisha框架,bootstrap-table组件增加固定列功能

需要引入 bootstrap-table-fixed-columns.css和bootstrap-table-fixed-columns.js文件 文件代码&#xff1a; bootstrap-table-fixed-columns.css样式文件代码 .fixed-table-header-columns, .fixed-table-body-columns {position: absolute;background-color: #fff;displa…

【Vue3】3-2 : 组件的概念及组件的基本使用方式

本书目录&#xff1a;点击进入 一、组件的概念 1.1、【案例】评分组件与按钮组件的抽离过程 二、组件的使用 - 抽离结构 2.1、【案例】简易首页 &#xff1e; 效果 &#xff1e; 代码 - 原始 &#xff1e; ​​​​​​​代码 - 组件抽离结构 &#xff1e; ​​​​…

【汇编】实验11 编写子程序

综合一下学过的指令就行了&#xff0c;比较简单。 assume cs:code data segmentdb "Beginners All-purpose Symbolic Instruction Code.",0 data ends code segment begin:mov ax,datamov ds,axmov si,0call lettercmov ax,4c00hint 21h letterc:mov cl,[si]mov ch,…

【线路图】世微AP5160宽电压降压型恒流芯片 LED电源 带调光SOT23-6

这是一款14-18V 3A 电流的PCB设计方案. 运用的是世微AP5160 电源驱动IC,这是一款效率高&#xff0c;稳定可靠的 LED 灯恒流驱动控制芯片&#xff0c;内置高精度比较器&#xff0c;固定 关断时间控制电路&#xff0c;恒流驱动电路等&#xff0c;特别适合大功率 LED 恒流驱动。 …

Wpf 使用 Prism 实战开发Day12

待办事项接口增删&#xff08;CURD&#xff09;改查实现 一.添加待办事项控制器&#xff08;ToDoController&#xff09; 控制器类需要继承 ControllerBase 基类需要添加 [ApiController] 特性以及 [Route] 特性Route&#xff08;路由&#xff09; 特性参数规则&#xff0c;一般…

pycharm debug显示的变量过多

问题&#xff1a; https://blog.csdn.net/Hodors/article/details/117535731 解决方法&#xff1a; 把"Show console variables by default"前面的勾取消掉就行 参考&#xff1a; https://stackoverflow.com/questions/48969556/hide-console-variables-in-pychar…

【Leetcode 程序员面试金典 02.08】 —— 环路检测 |双指针

面试题02.08. 环路检测 给定一个链表&#xff0c;如果它是有环链表&#xff0c;实现一个算法返回环路的开头节点。若环不存在&#xff0c;请返回null。 如果链表中有某个节点&#xff0c;可以通过连续跟踪next指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的…

abap 将xstring转换成PDF展示

收到外围系统的xstring之后&#xff0c;如何在sap中将其打开呢 1.创建一个屏幕 2.绘制一个customer control 3.创建流逻辑 4.流逻辑如下&#xff1a; DATA: go_html_container TYPE REF TO cl_gui_custom_container, go_html_control TYPE REF TO cl_gui_html_viewer, lv_u…

基于SSM的社区老年人关怀服务系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

OpenCV-Python(42):摄像机标定

目标 学习摄像机畸变以及摄像机的内部参数和外部参数根据摄像机相关参数对畸变图像进行修复 基础说明 今天的低价单孔摄像机(照相机)会给图像带来很多畸变。畸变主要有两种:径向畸变和切向畸变。如下图所示用红色直线将棋盘的两个边标注出来&#xff0c;但是你会发现棋盘的边…

C++力扣题目40--组合总和II

力扣题目链接(opens new window) 给定一个数组 candidates 和一个目标数 target &#xff0c;找出 candidates 中所有可以使数字和为 target 的组合。 candidates 中的每个数字在每个组合中只能使用一次。 说明&#xff1a; 所有数字&#xff08;包括目标数&#xff09;都是…

Linux Mii management/mdio子系统分析之五 PHY状态机分析及其与net_device的关联

&#xff08;转载&#xff09;原文链接&#xff1a;https://blog.csdn.net/u014044624/article/details/123303714 前面几章基本上完成了mdio模块驱动模型的分析&#xff0c;本篇文章主要讲述phy device的状态机以及phy device与net_device的关联。Phy device主要是对phy的抽象…

[LitCTF 2023]easy_shark

解压缩&#xff0c;发现需要输入密码&#xff0c;使用010打开&#xff0c;发现frflags和deflags都被修改了&#xff0c;这就会造成压缩包伪加密 把他们都改为0&#xff0c;再打开 将流量包使用wirshark打开 过滤http&#xff0c;并追踪 得到以下信息 看到了一个类似于flag格…

Graham扫描凸包算法

凸包&#xff08;Convex Hull&#xff09;是包含给定点集合的最小凸多边形。凸包算法有多种实现方法&#xff0c;其中包括基于递增极角排序、Graham扫描、Jarvis步进法等。下面&#xff0c;我将提供一个简单的凸包算法实现&#xff0c;基于Graham扫描算法。 Graham扫描算法是一…

hf-mirror 使用

文章目录 命令下载搜索下载gated model 根据这篇文章&#xff1a; 大模型下载使我痛苦 得知 Huggingface 镜像站 https://hf-mirror.com 命令下载 网站首页会介绍下载方法 更多用法&#xff08;多线程加速等&#xff09;详见这篇文章。简介&#xff1a; 方法一&#xff1a;…

DBeaver安装步骤

DBeaver 是一个基于 Java 开发&#xff0c;免费开源的通用数据库管理和开发工具&#xff0c;使用非常友好的 ASL 协议。可以通过官方网站或者 Github 进行下载。 由于 DBeaver 基于 Java 开发&#xff0c;可以运行在各种操作系统上&#xff0c;包括&#xff1a;Windows、Linux…

用Photoshop来制作GIF动画

录了个GIF格式的录屏文件&#xff0c;领导让再剪辑下&#xff0c;于是用Photoshop2023进行剪辑&#xff0c;录屏文件有约1400帧&#xff0c;PS保存为GIF格式时&#xff0c;还是挺耗时的&#xff0c;平时少用PS来进行GIF剪辑&#xff0c;编辑后的GIF不能动&#xff0c;网上搜索的…

Servlet- Response

一、预览 介绍完Servlet-Resquest的相关内容后&#xff0c;接下来就是Servlet- Response的内容。读者阅读完本篇文章后将可以自如地解析请求、设置响应&#xff0c;完成对客户端的响应。 二、Response体系结构 Response的体系结构与Request完全一样&#xff0c;其中ServletRe…