golang gin框架 Context自定义拓展

2023-11-05

golang gin框架 Context自定义拓展

有些时候会遇到gin.Context自带属性或方法无法满足开发需求的情况,可以对gin.Context进行一定的拓展和自定义

大致拓展效果如下,可以新增属性和方法

func main() {
	server := core.NewMyServer()
	//这里将是自定义拓展的MyContext,不再是gin.Conext
	server.GET("/test", func(c *core.MyContext) { 
		c.ID = 1  //新增ID属性
		c.Hello() //新增Hello()方法
	})

	server.GET("/login", controller.Login)
	v1 := server.Group("/v1")
	{
		v1.Use(middleware.Auth())
		v1.GET("/users", controller.Users)
		v1.GET("/detail",controller.UserDetail)
		v1.POST("/update", controller.UpdateUser)
	}

	_ = server.Run()
}

一、入门拓展方法

★目录结构

project
── controller
   └─ example.go
── core
   └─ context.go
main.go

★参考代码

1、拓展gin.Context,增加 用户ID 属性,增加 Hello() 方法
2、此处代码存放在project → core → context.go

//MyContext 拓展gin.Context后的MyContext
type MyContext struct {
	*gin.Context
	ID int
}

//HandleFunc 实现gin.Context到自定义MyContext的转换。
func HandleFunc(handler func(c *MyContext)) func(ctx *gin.Context) {
	return func(c *gin.Context) {
		handler(&MyContext{Context: c})
	}
}

//Hello 响应测试数据
func (c *MyContext) Hello() {
	c.JSON(http.StatusOK, gin.H{
		"code":    0,
		"message": "测试成功",
		"data":    "Hello!" + strconv.Itoa(c.ID),
	})
}

1、完成控制器代码
2、此处代码存放在project → controller → example.go

func Example(c *core.MyContext) {
	c.ID = 99
	c.Hello()
}

1、主函数运行测试
2、此处代码存放在project → main.go

func main() {
	server := gin.Default()
	/*这里所有路由都要使用HandleFunc进行转换,强迫症可能会难受,下文有解决方案。*/
	server.GET("/example", core.HandleFunc(controller.Example)) 
	_ = server.Run()
}

★测试结果

测试结果


二、优化拓展方法

路由定义时,每个方法都调用HandleFunc进行转换,看起来非常难受,这里用一些手段进行消除。

★目录结构

project
── controller
   └─ example.go
── core
   └─ context.go
main.go

★参考代码

1、优化上文中的代码
2、此处代码存放在project → core → context.go

type MyServer struct {
	*gin.Engine
}

//MyContext 拓展gin.Context后的MyContext
type MyContext struct {
	*gin.Context
	ID int
}

//MyRouterGroup 拓展后的自定义gin.RouterGroup
type MyRouterGroup struct {
	*gin.RouterGroup
}

//NewMyServer 新建gin服务器
func NewMyServer() *MyServer {
	myServer := &MyServer{Engine: gin.Default()}
	return myServer
}

//handleFunc 实现gin.Context到自定义Context的转换。
func handleFunc(handler func(c *MyContext)) func(ctx *gin.Context) {
	return func(c *gin.Context) {
		handler(&MyContext{Context: c})
	}
}

//Group 重写路由组注册
func (server *MyServer) Group(relativePath string, handlers ...func(c *MyContext)) *MyRouterGroup {
	RHandles := make([]gin.HandlerFunc, 0)
	for _, handle := range handlers {
		RHandles = append(RHandles, handleFunc(handle))
	}
	return &MyRouterGroup{server.Engine.Group(relativePath, RHandles...)}
}

//GET 拓展Get请求(根)
func (server *MyServer) GET(relativePath string, handlers ...func(c *MyContext)) gin.IRoutes {
	RHandles := make([]gin.HandlerFunc, 0)
	for _, handle := range handlers {
		RHandles = append(RHandles, handleFunc(handle))
	}
	return server.Engine.GET(relativePath, RHandles...)
}

//POST 拓展POST请求(根)
func (server *MyServer) POST(relativePath string, handlers ...func(c *MyContext)) gin.IRoutes {
	RHandles := make([]gin.HandlerFunc, 0)
	for _, handle := range handlers {
		RHandles = append(RHandles, handleFunc(handle))
	}
	return server.Engine.POST(relativePath, RHandles...)
}

//GET 拓展Get请求(子)
func (r *MyRouterGroup) GET(relativePath string, handlers ...func(c *MyContext)) gin.IRoutes {
	rHandles := make([]gin.HandlerFunc, 0)
	for _, handle := range handlers {
		rHandles = append(rHandles, handleFunc(handle))
	}
	return r.RouterGroup.GET(relativePath, rHandles...)
}

//POST 拓展Post请求(子)
func (r *MyRouterGroup) POST(relativePath string, handlers ...func(c *MyContext)) gin.IRoutes {
	rHandles := make([]gin.HandlerFunc, 0)
	for _, handle := range handlers {
		rHandles = append(rHandles, handleFunc(handle))
	}
	return r.RouterGroup.POST(relativePath, rHandles...)
}

//Use 拓展中间件注册
func (r *MyRouterGroup) Use(middlewares ...func(c *MyContext)) gin.IRoutes {
	rMiddlewares := make([]gin.HandlerFunc, 0)
	for _, middleware := range middlewares {
		rMiddlewares = append(rMiddlewares, handleFunc(middleware))
	}
	return r.RouterGroup.Use(rMiddlewares...)
}

//Hello 打印Hello!+MyContext中的ID
func (c *MyContext) Hello() {
	c.JSON(http.StatusOK, gin.H{
		"code":    0,
		"message": "测试成功",
		"data":    "Hello!" + strconv.Itoa(c.ID),
	})
}

1、控制器代码分Root和Node
2、此处代码存放在project → controller→ example.go

func RootExample(c *core.MyContext) {
	c.ID = 10
	c.Hello()
}

func NodeExample(c *core.MyContext) {
	c.ID = 20
	c.Hello()
}

1、主函数运行测试
2、此处代码存放在project → main.go

func main() {
	server := core.NewMyServer()

	server.GET("/root", controller.RootExample)

	v1 := server.Group("/v1")
	{
		v1.GET("/node", controller.NodeExample)
	}

	_ = server.Run()
}

★测试结果

root测试结果
node测试结果

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

golang gin框架 Context自定义拓展 的相关文章

  • 如何从 golang fyne 容器中删除对象

    我正在开发 GUI 应用程序 需要动态添加和删除 gui 元素 我想知道是否有办法从 golang fyne 容器中删除元素 在下面的示例代码中 我创建了容器并动态添加元素 现在我希望能够删除这些元素而不是隐藏它们 我尝试的一个 解决方案
  • 命名和未命名类型

    问题 我最近开始阅读Golang规格手册 https golang org ref spec并陷入试图理解的困境有名和无名类型在相关部分 https golang org ref spec Types 我来自动态语言 这让我有点头疼 手册指
  • 在 Go 中解析 RFC-3339 / ISO-8601 日期时间字符串

    我尝试解析日期字符串 2014 09 12T11 45 26 371Z 在围棋中 该时间格式定义为 RFC 3339 日期时间 https datatracker ietf org doc html rfc3339 section 5 6
  • 防止使用 golang 服务器访问文件夹中的文件

    我在 golang 中有一个服务器可以处理这样的文件夹路径 fs http FileServer http Dir assets http Handle Images fs http ListenAndServe 8000 nil 但在这个
  • 在 Go 中,如何将函数的 stdout 捕获到字符串中?

    例如 在 Python 中 我可以执行以下操作 realout sys stdout sys stdout StringIO StringIO some function prints to stdout get captured in t
  • 正则表达式不匹配

    我正在尝试以下代码 d byte x01 x00 x00 x00 x00 x00 x00 x00 x00 x00 x00 x80J x13 x80SQ x80L xe0 x80 x92 x80L x80H xe0 r regexp Must
  • 在 Go 中读取请求负载?

    我正在使用文件上传器 需要请求负载中的详细信息来裁剪它 func Upload w http ResponseWriter r http Request reader err r MultipartReader if err nil htt
  • golang导入结构体指针

    好的 我有一个主包和一个 http 处理程序包 本质上我想做的是设置一个全局结构 这样我就可以随时调用该结构中的信息 我尝试的示例的基本概要如下 主包导入处理函数 主包调用handlerfunc Handlerfunc 将 http Res
  • 无法封送,(实现encoding.BinaryMarshaler)。具有多个对象的 go-redis Sdd

    我有下面一段代码 我试图将一个数组添加到 redis 集中 但它给了我一个错误 package main import encoding json fmt github com go redis redis type Info struct
  • Bash脚本无法执行Go命令

    我正在尝试编写一个 bash 脚本来自动在不同的目录中运行 go get install 相关部分在这里 cd web go get cd web go install cd services go get cd services go i
  • Google App Engine Golang 没有这样的文件或目录

    我正在用 Go 开发一个 Google App Engine 项目 并陷入了读取文件的困境 事实上 应用程序在本地运行得很好 然而 部署时 它会恐慌告诉我没有这样的文件或目录 这是我的 fileValue 方法 func fileValue
  • 优化 golang 中的数据结构/字对齐填充

    与我在 C 中学到的类似 我相信填充导致了两个结构体实例大小的差异 type Foo struct w byte 1 byte x byte 1 byte y uint64 8 bytes type Bar struct x byte 1
  • Go API 在 html 中显示 swagger api 规范 (json) (Swagger UI)

    我有一个服务于特定端口的应用程序 gorilla mux 我也有一个 json 文件形式的 swagger API 规范 是否有任何 go API 可以像 spring boot 一样从 JSON 文件生成 swagger UI 定义 我正
  • Golang - 更改 Windows 上的构建工作路径

    我正在使用 SublimeText3 GoSublime 插件 在 Windows 8 上测试简单的 Go 程序 go run v example go 在运行之前它正在内部编译 应用程序数据 本地 温度 目录 我的防病毒程序认为这是病毒并
  • 在 Go 中使用电子邮件地址创建证书签名请求 (CSR)

    我尝试使用 crypto x509 包生成 CSR 但没有找到将 emailAddress 字段添加到其主题中的方法 根据文档证书申请 http golang org pkg crypto x509 CertificateRequest结构
  • Go 无法推断赋值中的类型:“non-name on left side of :=”

    该片段按预期工作play golang org p VuCl OKMav http play golang org p VuCl OKMav i 10 next 11 prev i i next 然而这个几乎相同的片段给出了non name
  • Gorm 总是返回带有 nil 值的结构

    我正在使用 Gorm 构建 Go Web API 作为 Amazon RDS 中 Postgresql 数据库的 ORM 问题是 Gorm 总是返回一片结构 其值全部为零 尽管数据库已经填充了数据 切片中的结构体数量是否合适取决于LIMIT
  • 为什么 Go 中只有 int 而没有 float?

    在 Go 中 有这样的类型int这可能相当于int32 or int64取决于系统架构 我可以声明一个整数变量而不用担心它的大小 var x int 为什么没有这个类型float 这相当于float32 or float64取决于我的系统架
  • 重新插入通道导致死锁

    我有稳定的入站 作业 流 将其输入到无缓冲通道中 我有一个for range循环来迭代项目并处理它们 如果处理该项目失败 我会将项目重新插入通道中 以便稍后重试 问题是当我将项目重新插入通道时 它陷入僵局 我明白为什么会发生这种情况 处理器
  • 编写每个处理程序中间件

    我希望从处理程序中提取一些重复的逻辑 并将其放入一些每个处理程序的中间件中 特别是 CSRF 检查 检查现有会话值 即身份验证或预览页面 等 我读了关于此的几篇文章 http justinas org writing http middle

随机推荐

  • Linux常用命令大全(详细版)

    目录 1 Linux管理文件和目录的命令 2 有关磁盘空间的命令 3 文件备份和压缩命令 4 有关关机和查看系统信息的命令 5 管理使用者和设立权限的命令 6 线上查询的命令 7 文件阅读的命令 8 网络操作命令 9 其他命令 详细版本 1
  • Spring常用注解(绝对经典),全靠这份Java知识点PDF大全

    Bean public ColorFactoryBean colorFactoryBean return new ColorFactoryBean 创建一个spring定义的FactoryBean public class ColorFac
  • 原生js实现导航栏拖拽滑动(适用于pc端和手机端)

    先贴一张动图看看效果吧 下面把代码贴上注释都在代码边上
  • 【PyTorch】torch.utils.data.Dataset 介绍与实战

    文章目录 一 前言 二 torch utils data Dataset 是什么 1 干什么用的 2 长什么样子 三 通过继承 torch utils data Dataset 定义自己的数据集类 四 为什么要定义自己的数据集类 五 实战
  • 什么是多态?如何实现?只看这一篇就够了

    1 多态的概念 1 1 概念 多态的概念 通俗来说 就是多种形态 具体点就是去完成某个行为 当不同的对象去完成时会产生出不同的状态 2 多态的定义及实现 2 1多态的构成条件 多态是在不同继承关系的类对象 去调用同一函数 产生了不同的行为
  • 在任务管理器结束某些任务后电脑突然白屏

    1 问题描述 任务管理器 可以通过单击右键电脑底部任务栏找到 快捷键 ctrl shfit esc 一般我们可以在 任务管理器 中强制结束一些任务 尤其是电脑特别卡的时候 但是 有时候一不留神 不知道结束了什么任务 电脑突然就白屏了 2 解
  • 【算法与数据结构】530、LeetCode二叉搜索树的最小绝对差

    文章目录 一 题目 二 解法 三 完整代码 所有的LeetCode题解索引 可以看这篇文章 算法和数据结构 LeetCode题解 一 题目 二 解法 思路分析 二叉搜索树的性质是左子树的所有节点键值小于中间节点键值 右子树的所有节点键值大于
  • C语言快速入门(2)

    目录 1 常量 1 1字面常量 1 2const修饰的常变量 1 3 define定义的标识符常量 1 4枚举常量 2 字符串和转义字符 2 1字符串 2 2转义字符 3 注释 4 选择语句 5 循环语句 6 函数 7 数组 7 1数组的定
  • css实现单行,多行文本超出文本显示省略号

    1 单行文本 div width 100px 必须要设置 overflow hidden 超出部分隐藏 white space nowrap 禁止换行 强制文本在一行显示 text overflow ellipsis 溢出文本显示省略号 使
  • to load JavaHL Library解决方法

    解决方法 Window Preferences Team SVN 在SVN接口的下拉框可以看到 默认选择的是JavaHL JNI Not Available 手动更改为SVNKit Pure Java SVNKit v1 3 5 7406
  • msys2安装与配置: 在windows上使用linux工具链g++和包管理工具pacman C++开发

    文章目录 为什么用这个msys2 下载 doc 安装 很简单 初次运行 做些配置 更新 软件安装与卸载方法 安装必要的软件包 设置win环境变量 在windows terminal中使用 在vscode中使用 为什么用这个msys2 方便w
  • OSPF详解及简单配置

    动态路由协议 直连路由器之间构建邻居关系 通过收发各类数据包进行共享信息 来获取未知的路由信息 基于某种算法自动生成未知网段最优路径的解 将其加载在路由表中 判断一个网络协议的好坏 通常关注三方面 收敛速度快 占用资源少 选路佳 各类协议的
  • Aspose最新版22.8教程

    直接上代码 用vs开发工具写一段代码 word转pdf new Document this txtWordFile Text Save new pdf new PdfSaveOptions 编译 生成exe 打开dnspy 将生成的exe和
  • 王姓名字大全

    土 王 士 王 健 王雯新 王美玲 王 振 王诗雅 王博岩 王 一 王德丹 王竣臣 王资存 王 一 王宇陈 王 颖 王淑华 王骏臣 王阳菲 王孜臣 王 三 王 婷 王 樱 王 莉 王鹏哲 王玺毓 王新华 王 任 王之惠 王韬涵 王添乐 王孝
  • 超详细前端面试八股文

    今天在掘金看到一篇特别好的前端八股文 链接 连八股文都不懂还指望在前端混下去么 掘金
  • Vue结合路由配置递归实现菜单栏

    转载 https www cnblogs com HouJiao p 13139901 html 完整代码在码云 https gitee com zhuxueling router menu git 在日常开发中 项目中的菜单栏都是已经实现
  • java与数据库连接odbc_详解java数据库连接之JDBC-ODBC桥连方式

    java数据库连接方式有两种 其中JDBC ODBC桥连方式属于之一 JDBC ODBC桥连方式连接数据库适用于JDK1 8之前的JDK版本 具体的连接过程详见下文 详析JDBC ODBC桥连方式 JDK提供JDBC接口 JDBC是一种可以
  • CMake基本语法

    操作数 类型 分类 BOOL STRING PATH FILEPATH 配置变量类型 LIST 转换 推导 具名 声明周期 set 声明 具名 unset取消 定义一个变量 判断是否定义用DEFINED set lt 变量名 gt lt 变
  • 【python自动化办公】Python自动化之Excel——openpyxl 模块(入门)

    前言 1 学习python自动化办公目的 学会使用python自动化处理文件 减少重复劳动 科学管理文件 能够不再使用别的软件合并 分割PDF等 2 未来持续打卡内容 Task03 Python与word和PDF Task04 简单的Pyt
  • golang gin框架 Context自定义拓展

    golang gin框架 Context自定义拓展 有些时候会遇到gin Context自带属性或方法无法满足开发需求的情况 可以对gin Context进行一定的拓展和自定义 大致拓展效果如下 可以新增属性和方法 func main se