1.go web之gin框架

news2025/2/26 8:22:11

Gin框架

一、准备

1.下载依赖

 go get -u github.com/gin-gonic/gin

2.引入依赖

import "github.com/gin-gonic/gin"

3. (可选)如果使用诸如 http.StatusOK 之类的常量,则需要引入 net/http 包

import "net/http"

二、基本使用

1. 配置路由

package main

import "github.com/gin-gonic/gin"

func main() {
	// 创建一个默认的路由引擎
	r := gin.Default()
	// 配置路由
	r.GET("/getInfo", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"msg": "成功",
		})
	})
	//启动 HTTP 服务,在8088端口监听
	r.Run(":8088")
}

在这里插入图片描述

三、Gin中的路由

1.路由概述

在 RESTful 架构中,每个网址代表一种资源,不同的请求方式表示执行不同的操作:

请求方式一般对应操作
GET(SELECT)从服务器取出资源(一项或多项)
POST(CREATE))在服务器新建一个资源
PUT(UPDATE)在服务器更新资源(客户端提供改变后的完整资源)
DELETE(DELETE))从服务器删除资源

2.简单路由

GET请求
r.GET("网址", func(c *gin.Context) {
c.String(200, "Get")
})
POST请求
r.POST("网址", func(c *gin.Context) {
c.String(200, "POST")
})
PUT请求
r.PUT("网址", func(c *gin.Context) {
c.String(200, "PUT")
})
DELETE请求
r.DELETE("网址", func(c *gin.Context) {
c.String(200, "DELETE")
})
动态路由
	r.GET("/getUser/:id", func(c *gin.Context) {
		id := c.Param("id")
		c.JSON(200, gin.H{
			"id":  id,
			"msg": "成功",
		})
	})

在这里插入图片描述

四、 响应格式

这里主要介绍使用比较多的字符串格式和json格式

c.String()

	r.GET("/getStr", func(c *gin.Context) {
		c.String(200, "成功")

	})

响应结果为字符串
在这里插入图片描述

c.JSON()

	r.GET("/getInfo", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"msg": "成功",
		})
	})

响应结果为json格式
在这里插入图片描述

五、路由传参

1.GET请求传值

请求路径: /user?uid=20&page=1

后端接收

router.GET("/user", func(c *gin.Context) {
//c.Query()接收请求GET请求路径参数
uid := c.Query("uid")
//c.DefaultQuery()接收请求GET请求路径参数,接收不到时,采用默认参数
page := c.DefaultQuery("page", "0")
c.String(200, "uid=%v page=%v", uid, page)
})

2.Post 请求传值(获取 form 表单)

请求路径:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form action="/doAddUser" method="post">
用户名:<input type="text" name="username" />
密码: <input type="password" name="password" />
<input type="submit" value="提交">
</form>
</body>
</html>

后端接收

router.POST("/doAddUser", func(c *gin.Context) {
//c.PostForm()接收form表单数据,key要与form表单name属性对应
username := c.PostForm("username")
password := c.PostForm("password")
//c.PostForm()接收form表单数据,接收不到采用默认值,key要与form表单name属性对应
age := c.DefaultPostForm("age", "20")
c.JSON(200, gin.H{ "usernmae": username, "password": password, "age": age, })
})

3.动态路由传值

请求路径:/user/20

后端接收

r.GET("/user/:uid", func(c *gin.Context) {
//c.Param()接收动态路由参数
uid := c.Param("uid")
c.String(200, "userID=%s", uid)
})

4.GET,POST 传递的结构体数据

Get 传值绑定到结构体

请求路径: /?username=zhangsan&password=123456

后端接收

//注意首字母大写
type Userinfo struct {
Username string `form:"username" json:"user"`
Password string `form:"password" json:"password"` }


router.GET("/", func(c *gin.Context) {
var userinfo Userinfo
if err := c.ShouldBind(&userinfo); err == nil {
c.JSON(http.StatusOK, userinfo)
} else {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
}
})
Post 传值绑定到结构体

请求路径:
在这里插入图片描述

后端接收

router.POST("/doLogin", func(c *gin.Context) {
var userinfo Userinfo
if err := c.ShouldBind(&userinfo); err == nil {
c.JSON(http.StatusOK, userinfo)
} else {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
}
})

.ShouldBind()能够基于请求自动提
取 JSON、form 表单和 QueryString 类型的数据,并把值绑定到指定的结构体对象

六、路由组

func main() {
	router := gin.Default()
	// 简单的路由组: v1
	v1 := router.Group("/v1")
	{
		v1.POST("/login", loginEndpoint)
		v1.POST("/submit", submitEndpoint)
		v1.POST("/read", readEndpoint)
	}
	// 简单的路由组: v2
	v2 := router.Group("/v2")
	{
		v2.POST("/login", loginEndpoint)
		v2.POST("/submit", submitEndpoint)
		v2.POST("/read", readEndpoint)
	}
	router.Run(":8080")
}

七、Gin路由文件分组

新建 routes 文件夹,routes 文件下面新建 adminRoutes.goapiRoutes.go、defaultRoutes.go

新建adminRoutes

package routes

import (
	"net/http"

	"github.com/gin-gonic/gin"
)

func AdminRoutesInit(router *gin.Engine) {
	adminRouter := router.Group("/admin")
	{
		adminRouter.GET("/user", func(c *gin.Context) {
			c.String(http.StatusOK, "用户")
		})
		adminRouter.GET("/news", func(c *gin.Context) {
			c.String(http.StatusOK, "news")
		})
	}
}

新建apiRoutes.go

package routes

import (
	"net/http"

	"github.com/gin-gonic/gin"
)

func ApiRoutesInit(router *gin.Engine) {
	apiRoute := router.Group("/api")
	{
		apiRoute.GET("/user", func(c *gin.Context) {
			c.JSON(http.StatusOK, gin.H{"username": "张三",
				"age": 20})
		})
		apiRoute.GET("/news", func(c *gin.Context) {
			c.JSON(http.StatusOK, gin.H{"title": "这是新闻"})
		})
	}
}

新建defaultRoutes.go

package routes

import (
	"github.com/gin-gonic/gin"
)

func DefaultRoutesInit(router *gin.Engine) {
	defaultRoute := router.Group("/")
	{
		defaultRoute.GET("/", func(c *gin.Context) {
			c.String(200, "首页")
		})
	}
}

配置main.go

package main

import (
	"gin_demo/routes"
	"github.com/gin-gonic/gin"

//注意首字母大写
type Userinfo struct {
	Username string `form:"username" json:"user"`
	Password string `form:"password" json:"password"`
}

func main() {
	r := gin.Default()
	routes.AdminRoutesInit(r)
	routes.ApiRoutesInit(r)
	routes.DefaultRoutesInit(r)
	r.Run(":8080")
}

八、Gin中自定义控制器

控制器分组

1.新建controller/admin/NewsController.go
package admin

import (
	"net/http"

	"github.com/gin-gonic/gin"
)

type NewsController struct {
}

func (c NewsController) Index(ctx *gin.Context) {
	ctx.String(http.StatusOK, "新闻首页")
}
2.新建 controller/admin/UserController.go
package admin

import (
	"net/http"

	"github.com/gin-gonic/gin"
)

type UserController struct {
}

func (c UserController) Index(ctx *gin.Context) {
	ctx.String(http.StatusOK, "这是用户首页")
}
func (c UserController) Add(ctx *gin.Context) {
	ctx.String(http.StatusOK, "增加用户")
}
3.在路由文件分组中配置控制器(将处理中间件改为控制器的方法)
package routes

import (
	"gin_demo/controller/admin"

	"github.com/gin-gonic/gin"
)

func AdminRoutesInit(router *gin.Engine) {
	adminRouter := router.Group("/admin")
	{
		adminRouter.GET("/user", admin.UserController{}.Index)
		adminRouter.GET("/user/add", admin.UserController{}.Add)
		adminRouter.GET("/news", admin.NewsController{}.Add)
	}
}

九、路由中间件

通俗的讲:中间件就是匹配路由前和匹配路由完成后执行的一系列操作

Gin 中的中间件必须是一个 gin.HandlerFunc 类型,配置路由的时候可以传递多个 func 回调函
数,最后一个 func 回调函数前面触发的方法都可以称为中间件。

1.路由中间件基本使用

package main

import (
	"fmt"

	"github.com/gin-gonic/gin"
)

func initMiddleware(ctx *gin.Context) {
	fmt.Println("我是一个中间件")
}
func main() {
	r := gin.Default()
	r.GET("/", initMiddleware, func(ctx *gin.Context) {
		ctx.String(200, "首页--中间件演示")
	})
	r.GET("/news", initMiddleware, func(ctx *gin.Context) {
		ctx.String(200, "新闻页面--中间件演示")
	})
	r.Run(":8080")
}

2.ctx.Next()调用该请求的剩余处理程序

中间件里面加上 ctx.Next()可以让我们在路由匹配完成后执行一些操作
比如我们统计一个请求的执行时间。

package main

import (
	"fmt"
	"time"

	"github.com/gin-gonic/gin"
)

func initMiddleware(ctx *gin.Context) {
	fmt.Println("1-执行中中间件")
	start := time.Now().UnixNano()
	// 调用该请求的剩余处理程序
	ctx.Next()
	fmt.Println("3-程序执行完成 计算时间")
	// 计算耗时 Go 语言中的 Since()函数保留时间值,并用于评估与实际时间的差异
	end := time.Now().UnixNano()
	fmt.Println(end - start)
}
func main() {
	r := gin.Default()
	r.GET("/", initMiddleware, func(ctx *gin.Context) {
		fmt.Println("2-执行首页返回数据")
		ctx.String(200, "首页--中间件演示")
	})
	r.GET("/news", initMiddleware, func(ctx *gin.Context) {
		ctx.String(200, "新闻页面--中间件演示")
	})
	r.Run(":8080")
}

3.全局中间件

package main

import (
	"fmt"

	"github.com/gin-gonic/gin"
)

func initMiddleware(ctx *gin.Context) {
	fmt.Println("全局中间件 通过 r.Use 配置")
	// 调用该请求的剩余处理程序
	ctx.Next()
}
func main() {
	r := gin.Default()
	//注册全局中间件
	r.Use(initMiddleware)
	r.GET("/", func(ctx *gin.Context) {
		ctx.String(200, "首页--中间件演示")
	})
	r.GET("/news", func(ctx *gin.Context) {
		ctx.String(200, "新闻页面--中间件演示")
	})
	r.Run(":8080")
}

4.在路由分组中配置中间件

写法一:

shopGroup := r.Group("/shop", StatCost())
{
shopGroup.GET("/index", func(c *gin.Context) {...})
... }

写法二:

shopGroup := r.Group("/shop")
shopGroup.Use(StatCost())
{
shopGroup.GET("/index", func(c *gin.Context) {...})
... }

十、中间件和对应控制器之间共享数据

1.设置值

func InitAdminMiddleware(ctx *gin.Context) {
	// 可以通过 ctx.Set 在请求上下文中设置值,后续的处理函数能够取到该值
	ctx.Set("username", "张三")
}

2.获取值

func (c UserController) Index(ctx *gin.Context) {
	username, _ := ctx.Get("username")
}

十一、中间件注意事项

gin 默认中间件
gin.Default()默认使用了 Logger 和 Recovery 中间件,其中:
• Logger 中间件将日志写入 gin.DefaultWriter,即使配置了 GIN_MODE=release。
• Recovery 中间件会 recover 任何 panic。如果有 panic 的话,会写入 500 响应码。
如果不想使用上面两个默认的中间件,可以使用 **gin.New()**新建一个没有任何默认中间件的路由

gin 中间件中使用 goroutine
当在中间件或 handler 中启动新的 goroutine 时,不能使用原始的上下文(c *gin.Context),
必须使用其只读副本(c.Copy())

r.GET("/", func(c *gin.Context) {
	//拷贝副本
	cCp := c.Copy()
	go func() {
	// simulate a long task with time.Sleep(). 5 seconds
	time.Sleep(5 * time.Second)
	// 这里使用你创建的副本
	fmt.Println("Done! in path " + cCp.Request.URL.Path)
	}()
	c.String(200, "首页")
})

十二、Gin中的Cookie

设置cookie

c.SetCookie(name, value string, maxAge int, path, domain string, secure, httpOnly bool)

获取cookie

cookie, err := c.Cookie("name")

完整demo

package main

import (
	"gin_demo/models"
	"github.com/gin-gonic/gin"
	"html/template"
)

func main() {
	r := gin.Default()
	r.SetFuncMap(template.FuncMap{"unixToDate": models.UnixToDate})
	r.GET("/", func(c *gin.Context) {
		//设置cookie
		c.SetCookie("usrename", "张三", 3600, "/", "localhost", false, true)
		c.String(200, "首页")
	})
	r.GET("/user", func(c *gin.Context) {
		//获取cookie
		username, _ := c.Cookie("usrename")
		c.String(200, "用户-"+username)
	})
	r.Run(":8080")
}

十三、Gin中的Session

Gin 官方没有给我们提供 Session 相关的文档,这个时候我们可以使用第三方的 Session 中间件来实现
session

gin-contrib/sessions 中间件支持的存储引擎:
• cookie
• memstore
• redis
• memcached
• mongodb

1.安装session包

go get github.com/gin-contrib/sessions

2.基本session用法

package main

import (
	"github.com/gin-contrib/sessions"
	"github.com/gin-contrib/sessions/cookie"
	"github.com/gin-gonic/gin"
)

func main() {
	r := gin.Default()
	// 1.创建基于 cookie 的存储引擎,secret11111 参数是用于加密的秘钥
	store := cookie.NewStore([]byte("secret11111"))
	// 设置 session 中间件,参数 mysession,指的是 session 的名字,也是 cookie 的名字
	// 2.store 是前面创建的存储引擎,我们可以替换成其他存储引擎
	r.Use(sessions.Sessions("mysession", store))
	r.GET("/", func(c *gin.Context) {
		//初始化 session 对象
		session := sessions.Default(c)
		//设置过期时间
		session.Options(sessions.Options{
			MaxAge: 3600 * 6, // 6hrs
		})
		//设置 Session
		session.Set("username", "张三")
		session.Save()
		c.JSON(200, gin.H{"msg": session.Get("username")})
	})
	r.GET("/user", func(c *gin.Context) {
		// 初始化 session 对象
		session := sessions.Default(c)
		// 通过 session.Get 读取 session 值
		username := session.Get("username")
		c.JSON(200, gin.H{"username": username})
	})
	r.Run(":8000")
}

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

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

相关文章

css 星星闪烁加载框

今天带来的是普灵普灵的loader闪烁加载框 效果如下 开源精神给我们带来了源码 ,源码如下 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, in…

LangChain的发展史

LangChain 发展史 LangChain 的作者是 Harrison Chase&#xff0c;最初是于 2022 年 10 月开源的一个项目&#xff0c;在 GitHub 上获得大量关注之后迅速转变为一家初创公司。2017 年 Harrison Chase 还在哈佛上大学&#xff0c;如今已是硅谷的一家热门初创公司的 CEO&#xf…

绘制X-Bar-S和X-Bar-R图,监测过程,计算CPK过程能力指数

X-Bar-S图和X-Bar-R图是统计质量控制中常用的两种控制图&#xff0c;用于监测过程的稳定性和一致性。它们的主要区别在于如何计算和呈现数据的变化以及所关注的问题类型。 X-Bar-S图&#xff08;平均值与标准偏差图&#xff09;&#xff1a; X-Bar代表样本均值&#xff0c;S代表…

制造业中CRM系统的作用有哪些

CRM系统是企业信息化建设的一部分&#xff0c;制造企业要想在疫情残酷的市场环境中生存下去离不开客户资源&#xff0c;因此我们说制造业CRM系统是当下企业数字化、信息化的关键。制造业CRM系统的作用有哪些?一起来看看吧。 让销售过程更规范 制造业需要CRM系统规范化销售流…

2023年中国饲料酸化剂产量、需求量及市场规模分析[图]

饲料酸化剂又称酸度调节剂&#xff0c;作为新型的饲料添加剂&#xff0c;其作用是保持动物体内的电解质平衡&#xff0c;促进动物健康生长。饲料酸化剂的众多作用机理都源于其酸化效应&#xff0c;即通过降低消化道中pH值使影响动物生长、生产所需的一些相关因素得以很好地发挥…

leetcodeT912-快排优化-三路划分

leetcodeT912-快排优化-三路划分 1.前言2.为什么需要三路划分的优化?3.三路划分的思想及举例画图4.三路划分的代码实现5.三数取中修改 1.前言 因为快排的名声太大 并且快排在某些场景下比较慢,所以leetcode"修理"了一下快排 特意设计了一些专门针对快排的测试用例 所…

Windows 程序注册服务运行

文章目录 创建服务窗口功能AppilicationDetailsLog OnDependencies 编辑服务删除服务服务管理进程信息运行状态 可以使用 nssm、 easy-service 来管理&#xff0c;本文使用 NSSM 来操作 创建服务 使用 nssm install [<servicename>] 调出 UI 窗口&#xff0c;第三个参…

VS 断点调试技巧:直接看到成员变量,隐藏属性,跳过方法

问题描述 直接断点不能直接显示成员变量 可以改下ToString方法&#xff0c;但这个方法可能还有其他用途&#xff0c;不推荐 解决方法 类加标签&#xff1a;DebuggerDisplay 可以直接显示属性了&#xff0c;但是有密码私密属性或者不重要的属性&#xff0c;怎么隐藏呢 隐藏属性…

快手商品详情数据接口,快手商品详情API接口,快手API接口

在网页抓取方面&#xff0c;可以使用 Python、Java 等编程语言编写程序&#xff0c;通过模拟 HTTP 请求&#xff0c;获取快手网站上的商品页面。在数据提取方面&#xff0c;可以使用正则表达式、XPath 等方式从 HTML 代码中提取出有用的信息。值得注意的是&#xff0c;快手网站…

【k8s 开发排错】k8s组件开发排错之pprof

参考 Kubernetes组件问题排查的一些方法 - 知乎 go 程序性能调优 pprof 的使用 &#xff08;一&#xff09; - 润新知 Go进阶系列 之 性能分析神器pprof__好吗_好的的博客-CSDN博客 k8s各组件端口_k8s10259端口-CSDN博客 Go调试神器pprof使用教程【实战分享】_NPE~的博客-C…

Datawhale发布,首个AI Prompt 工程师计划!

Datawhale发布 联合&#xff1a;讯飞星火、开源学习高校联盟 无论你是新手还是有 AI 基础 只要你对 AI 方向感兴趣、有热情 Datawhale AI Prompt 工程师计划 联合科大讯飞星火大模型 面向在校学生、社会在职人士 提供 AI Prompt 的免费学习机会 通过考试可获官方颁发的 Promp…

《面试求职系列》(三):如何写简历及求职技巧

&#x1f499;个人主页: GoAI |&#x1f49a; 公众号: GoAI的学习小屋 | &#x1f49b;交流群: 704932595 |&#x1f49c;个人简介 &#xff1a; 掘金签约作者、百度飞桨PPDE、领航团团长、开源特训营导师、CSDN、阿里云社区人工智能领域博客专家、新星计划计算机视觉方向导师…

周四见|物流人的一周资讯

顺丰铁联多式联运平台示范工程被命名为“国家多式联运示范工程” 10月10日消息&#xff0c;交通运输部、国家发展改革委近日联合印发通知&#xff0c;决定命名中欧班列集装箱多式联运信息集成应用示范工程等19个项目为“国家多式联运示范工程”。其中&#xff0c;顺丰铁联多式…

如何测量GNSS信号和高斯噪声功率及载波比?

引言 本文将介绍如何测量德思特Safran GSG-7或GSG-8 GNSS模拟器的输出信号功率。此外&#xff0c;还展示了如何为此类测量正确配置德思特Safran Skydel仿真引擎以及如何设置射频设备&#xff0c;从而使用频谱分析仪准确测量信号的射频功率。 什么是载波噪声密度C/N0 GNSS接收…

OpenSM-QoS管理

目录 一、概述 二、完整QoS策略文件 三、简化QoS策略定义 四、策略文件语法规则 五、完整策略文件示例 六、简化的QoS策略 6.1 IPoIB 6.2 SDP 6.3 RDS 6.4 iSER 6.5 SRP 6.6 MPI 七、SL2VL映射和VL仲裁 缩写全拼中文SMSubnet Manager子网管理器&#xff08;实体&a…

精品Python的美食餐饮服务系统点餐订餐-可视化大屏

《[含文档PPT源码等]精品Python的美食餐饮服务系统的设计与实现-爬虫》该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程等&#xff01; 软件开发环境及开发工具&#xff1a; 开发语言&#xff1a;python 使用框架&#xff1a;Django 前端技术&#x…

学习开发一个RISC-V上的操作系统(汪辰老师) — 一次RV32I加法指令的反汇编

前言 &#xff08;1&#xff09;此系列文章是跟着汪辰老师的RISC-V课程所记录的学习笔记。 &#xff08;2&#xff09;该课程相关代码gitee链接&#xff1b; &#xff08;3&#xff09;PLCT实验室实习生长期招聘&#xff1a;招聘信息链接 前置知识 RISC-V 汇编指令编码格式 &a…

智慧机场数字孪生大屏升级智慧出行全方位服务

在宁波栎社国际机场的信息中心大楼内&#xff0c;一块大屏幕上展示了一座“数字孪生”机场。通过点击屏幕上的各个板块&#xff0c;可以实时查看现场情况&#xff0c;一旦出现突发状况&#xff0c;还可以立即启动闭环处置流程…… &#xff08;图源自宁波机场&#xff09; 在数…

7-zip压缩包密码忘记了,怎么破解?

7z压缩包设置了密码&#xff0c;解压的时候就需要输入正确对密码才能顺利解压出文件&#xff0c;正常当我们解压文件或者删除密码的时候&#xff0c;虽然方法多&#xff0c;但是都需要输入正确的密码才能完成。忘记密码就无法进行操作。 那么&#xff0c;忘记了7z压缩包的密码…

LLM应用架构 LLM application architectures

在本课程的最后一部分&#xff0c;您将探讨构建基于LLM的应用程序的一些额外考虑因素。首先&#xff0c;让我们把迄今为止在本课程中所见的一切汇总起来&#xff0c;看看创建LLM驱动应用程序的基本组成部分。您需要几个关键组件来创建端到端的应用程序解决方案&#xff0c;从基…