Gin简介
https://geektutu.com/post/quick-go-gin.html我是从这个网站上面摘录的,就是做个笔记,仅分享。膜拜极客兔兔大佬
Go特性:
-
快速:路由不使用反射,基于Radix树,内存占用少。
-
中间件 :HTTP请求,可先经过一系列中间件处理,例如:Logger,Authorization,GZIP等。这个特性和 NodeJs 的
Koa
框架很像。中间件机制也极大地提高了框架的可扩展性。 -
异常处理:服务始终可用,不会宕机。Gin 可以捕获 panic,并恢复。而且有极为便利的机制处理HTTP请求过程中发生的错误。
-
JSON :Gin可以解析并验证请求的JSON。这个特性对
Restful API
的开发尤其有用。 -
路由分组:例如将需要授权和不需要授权的API分组,不同版本的API分组。而且分组可嵌套,且性能不受影响。
-
渲染内置:原生支持JSON,XML和HTML的渲染
-
安装 Gin
go
go get -u -v github.com/gin-gonic/gin
-v
:打印出被构建的代码包的名字
-u
:已存在相关的代码包,强行更新代码包及其依赖包
第一个Gin程序
go
package main
import "github.com/gin-gonic/gin"
func main() {
r := gin.Default()
/*
使用gin.Default()生成了一个实例,这个实例就是一个接口标准------WSGI
WSGI是就是一个接口标准,用于实现Web应用程序和服务器之间的通信
*/
r.GET("/", func(c *gin.Context) { //声明一个路由,告诉什么样的URL能触发传入的函数
//这个函数返回我们想要显示在用户浏览器的信息
c.String(200, "Hello,Geektutu")
})
r.Run() //让应用运行在本地服务器上
}
路由(ROUTE)
路由方法有 GET, POST, PUT, PATCH, DELETE 和 OPTIONS ,还有Any,可匹配以上任意类型的请求。
获取Query参数,就是URL的一部分
$ curl "http://localhost:9999/users?name=Tom&role=student"
Tom is a student
go
r.GET("/user",func(c *gin.Context){
name := c.Query("name")
//对于name参数
role := c.DefaultQuery("role","teacher")
//对于role参数,如果没有,默认teacher
c.String(http.StatusOK,"%s is a %s",name,role)
})
获取POST参数
go
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func main() {
r := gin.Default()
/*
使用gin.Default()生成了一个实例,这个实例就是一个接口标准------WSGI
WSGI是就是一个接口标准,用于实现Web应用程序和服务器之间的通信
*/
r.POST("/form", func(c *gin.Context) {
username := c.PostForm("username")
password := c.DefaultPostForm("passwoed", "000000")
//获取表单上的password参数,如果参数不存在,就是用默认值0000000
c.JSON(http.StatusOK, gin.H{
"usernaem": username,
"password": password,
}) //返回一个JSON响应
/*
http.StatusOK是一个常量,表示HTTP响应状态码
中的成功状态,这个状态码表示服务器成功处理了请求
*/
})
}
Query 和 POST混合参数
go
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func main() {
r := gin.Default()
/*
使用gin.Default()生成了一个实例,这个实例就是一个接口标准------WSGI
WSGI是就是一个接口标准,用于实现Web应用程序和服务器之间的通信
*/
r.POST("/posts", func(c *gin.Context) {
id := c.Query("id")
page := c.DefaultQuery("page", "0")
username := c.PostForm("username")
password := c.DefaultPostForm("password", "000000")
c.JSON(http.StatusOK, gin.H{
"id": id,
"page": page,
"username": username,
"password": password,
})
})
/*
gin.H 是 Gin 框架中的一个类型,
它是一个简化版的 map[string]interface{},
通常用于构造 HTTP 响应中的 JSON 数据。
gin.H 类型允许您以一种更简洁的方式构建键值对,用于构建 JSON 响应。
*/
}
Map参数(字典参数)
go
r := gin.Default()
/*
使用gin.Default()生成了一个实例,这个实例就是一个接口标准------WSGI
WSGI是就是一个接口标准,用于实现Web应用程序和服务器之间的通信
*/
r.POST("/post", func(c *gin.Context) {
ids := c.QueryMap("ids")
names := c.PostFormMap("names")
c.JSON(http.StatusOK,gin.H{
"ids": ids,
"names": names,
})
})
重定向
go
r.GET("/redirect", func(c *gin.Context) {
c.Redirect(http.StatusMovedPermanently, "/index")
})
r.GET("/goindex", func(c *gin.Context) {
c.Request.URL.Path = "/"
r.HandleContext(c)//对请求重新处理
})
分组路由
这样就更好管理
在 Gin 框架中,您可以使用分组路由来将一组相关的路由归类到同一个路由组中,这样可以更好地组织和管理路由。
以下是如何在 Gin 中使用分组路由的示例:
go
goCopy codepackage main
import (
"github.com/gin-gonic/gin"
)
func main() {
router := gin.Default()
// 创建一个路由组
v1 := router.Group("/v1")
{
v1.GET("/users", func(c *gin.Context) {
c.JSON(200, gin.H{"message": "GET /v1/users"})
})
v1.POST("/users", func(c *gin.Context) {
c.JSON(200, gin.H{"message": "POST /v1/users"})
})
}
// 创建另一个路由组
v2 := router.Group("/v2")
{
v2.GET("/users", func(c *gin.Context) {
c.JSON(200, gin.H{"message": "GET /v2/users"})
})
v2.POST("/users", func(c *gin.Context) {
c.JSON(200, gin.H{"message": "POST /v2/users"})
})
}
router.Run(":8080")
}
在这个示例中,我们创建了两个路由组 "/v1" 和 "/v2",每个路由组都包含了一组相关的路由。例如,"/v1/users" 和 "/v2/users" 分别是两个路由组中的路由。这样做可以更好地组织和管理不同版本或不同功能的路由。
go
r := gin.Default()
//处理器函数:defaultHandler
defaultHandler := func(c *gin.Context){
c.JSON(http.StatusOK,gin.H{
"path":c.FullPath(),
})
}
//group :v1
v1 := r.Group("/v1")
{
v1.GET("/posts",defaultHandler)
v1.GET("/series",defaultHandler)
}
v2:=r.Group("/v2")
{
v2.GET("/post",defaultHandler)
v2.GET("/series",defaultHandler)
}
//只是首先进行分组,处理的时候还是到处理器函数
上传文件
单个文件
go
r := gin.Default()
r.POST("/upload1", func(c *gin.Context) {
file, _ := c.FormFile("file")/*获取名为"file"的文件*/
c.String(http.StatusOK,"%s uploaded!",file.Filename)
})
多个文件
go
r := gin.Default()
r.POST("/upload2", func(c *gin.Context) {
//Multipart form
form, _ := c.MultipartForm()
/*
获取表单中的多部份表单数据
*/
files := form.File["upload[]"] //获取名为"upload[]"的多个上传文件对象
//遍历文件对象列表
for _,file := range files{
log.Println(file.Filename)
}
c.String(http.StatusOK,"%d files uploaded!",len(files))
})
HTML模板
go
func main() {
r := gin.Default()
r.LoadHTMLGlob("C:\\Users\\Lenovo\\GolandProjects\\gin\\day_23\\template")
stu1 := &student{Name: "Geektutu", Age: 20}
stu2 := &student{Name: "Jack", Age: 22}
r.GET("/arr", func(c *gin.Context) {
c.HTML(http.StatusOK, "arr.html", gin.H{
"title": "Gin",
"stuArr": [2]*student{stu1, stu2},
})
})
/*
当用户访问/arr路径的时候,会执行该函数
在函数内部,我们会渲染名为"arr.html"的HTML模板文件,并且传递模板所需的数据
*/
}
感觉现在也解决不了这个问题,运行不了!算了算了
中间件
中间件可以接收 HTTP 请求对象和响应对象,并进行处理。通常,一个中间件会做一些预处理 ,然后将请求传递给下一个中间件或处理器函数。类似地,在响应阶段,中间件可能会修改响应对象,然后将其传递给下一个中间件或返回给客户端。
go
r := gin.Default()
//作用于全局
r.Use(gin.Logger())
r.Use(gin.Recovery())
//这些中间件将在每个请求处理之前都被调用
//作用于单个路由
r.GET("/benchmark", MyBenchLogger(), benchEndpoint)
// MyBenchLogger()中间件被应用到了benchEndpoint路由上
//作用于某个组
authorized := r.Group("/")
authorized.Use(AuthRequired())
{//AuthRequired()中间件被应用到名为authorized的路由组上
authorized.POST("/login", loginEndpoint)
authorized.POST("/submit", submitEndpoint)
}