GIN简单使用
Gin是一个golang的微框架,封装比较优雅,API友好,源码注释比较明确,已经发布了1.0版本。具有快速灵活,容错方便等特点。其实对于而言,web框架的依赖要远比Python,Java之类的要小。自身的net/http足够简单,性能也非常不错。框架更像是一些常用函数或者工具的集合。借助框架开发,不仅可以省去很多常用的封装带来的时间,也有助于团队的编码风格和形成规范。
gin简介
Gin是一个golang的微框架,封装比较优雅,API友好,源码注释比较明确,已经发布了1.0版本。具有快速灵活,容错方便等特点。其实对于golang而言,web框架的依赖要远比Python,Java之类的要小。自身的net/http足够简单,性能也非常不错。框架更像是一些常用函数或者工具的集合。借助框架开发,不仅可以省去很多常用的封装带来的时间,也有助于团队的编码风格和形成规范。
1 GIN初始
使用gin编写一个接口并返回对象
package main import "github.com/gin-gonic/gin" type Resource struct { Code int `json:"code"` Msg string `json:"msg"` Data map[string]any `json:"data"` } func Index(c *gin.Context) { c.JSON(200, Resource{ Code: 0, Msg: "成功", Data: map[string]any{"code": "段段"}, }) } func main() { //关闭多余的日志 debug gin.SetMode("release") //初始化 c := gin.Default() //定义路由 c.GET("index", Index) c.Run(":8080") }
-
c := gin.Default():这是默认的服务器。使用gin的
Default
方法创建一个路由Handler
; -
c.GET("index", Index) 然后通过Http方法绑定路由规则和路由函数。不同于
net/http
库的路由函数,gin进行了封装,把request
和response
都封装到了gin.Context
的上下文环境中。 -
最后启动路由的Run方法监听端口。还可以用
http.ListenAndServe(":8080", router)
,或者自定义Http服务器配置。 -
c.Run("127.0.0.1:8000") 只能本机访问
2 响应体
2.1 封装返回统一响应
建立res文件夹,放入响应代码
package res import "github.com/gin-gonic/gin" type Response struct { Code int `json:"code"` Msg string `json:"msg"` data any } var codeMap = map[int]string{ 10001: "权限错误", 10002: "角色错误", } func response(c *gin.Context, code int, msg string, data any) { c.JSON(code, Response{ Code: code, Msg: msg, data: data, }) } func Ok(c *gin.Context, msg string, data any) { response(c, 200, msg, data) } func OkWithData(c *gin.Context, data any) { Ok(c, "成功", data) } func OkWithMsg(c *gin.Context, msg string) { Ok(c, msg, make(map[string]any)) } func Fail(c *gin.Context, msg string, code int) { response(c, code, msg, nil) } func FailWithCode(c *gin.Context, code int) { msg, e := codeMap[code] if !e { msg = "服务错误" } response(c, 200, msg, nil) } func FailWithMsg(c *gin.Context, msg string) { response(c, 200, msg, nil) }
2.2 JSON响应测试
package main import ( "github.com/gin-gonic/gin" "go_stuty/res" ) func main() { g := gin.Default() g.GET("index", func(c *gin.Context) { c.JSON(200, gin.H{"msg": "成功", "data": map[string]any{"code": "段段"}, "code": 200}) }) g.POST("users", func(c *gin.Context) { res.Ok(c, "用户信息", gin.H{ "username": "段段", "age": 30, }) }) g.GET("login", func(c *gin.Context) { res.OkWithMsg(c, "登录成功") }) g.GET("fails", func(c *gin.Context) { res.FailWithCode(c, 10001) }) g.Run(":8080") }
2.3 HTML响应测试
package main import "github.com/gin-gonic/gin" func main() { g := gin.Default() //加载路径下所有文件 g.LoadHTMLGlob("templates/*") //单个文件加载 g.LoadHTMLFiles("templates/index.html") g.GET("index", func(c *gin.Context) { c.HTML(200, "index.html", map[string]string{"title": "段段主题"}) }) g.Run(":8080") }
1、注意绝对和相对路径加载问题
2、//加载路径下所有文件 g.LoadHTMLGlob("templates/*")
3、//单个文件加载 g.LoadHTMLFiles("templates/index.html")
4、前后端不分离的写法 map[string]string{"title": "段段主题"}
返回修改html主题
c.HTML(200, "index.html", map[string]string{"title": "段段主题"})
html
<title>{{.title}}</title>
5、部署方式
前后端分离
前端打包引入后端单独部署
2.4 文件响应测试
package main import "github.com/gin-gonic/gin" func main() { g := gin.Default() g.GET("download", func(c *gin.Context) { c.Header("Content-Type", "application/octet-stream") c.Header("Content-Disposition", "attachment;filename=index.html") c.File("templates/index.html") }) g.Run(":8080") }
Content-Type设置传输类型
只能GET请求
2.5 静态文件响应测试
package main import "github.com/gin-gonic/gin" func main() { g := gin.Default() //通过文件夹别名st 访问static下所有的文件 g.Static("st", "static") //通过别名 st 单独访问index.html // g.StaticFile("st", "static/index.html") g.Run(":8080") }
g.Static("st", "static") st别名 static文件夹路径
3、请求
3.1 请求参数
package main import ( "fmt" "github.com/gin-gonic/gin" ) func main() { g := gin.Default() g.GET("index", func(c *gin.Context) { name, _ := c.GetQuery("name") //多个参数的情况 key=123&key=456 key, _ := c.GetQueryArray("key") age, _ := c.GetQuery("age") fmt.Println(name, age, key) }) g.Run(":8080") }
请求连接 http://127.0.0.1:8080/index?name=%E6%AE%B5%E6%AE%B5&age=30&key=123&key=456
3.2 动态参数
package main import ( "fmt" "github.com/gin-gonic/gin" ) func main() { g := gin.Default() g.GET("index/:id/:name", func(c *gin.Context) { id := c.Param("id") name := c.Param("name") fmt.Println(name, id) }) g.Run(":8080") }
3.3 表单参数
package main import ( "fmt" "github.com/gin-gonic/gin" ) func main() { g := gin.Default() g.POST("index", func(c *gin.Context) { name := c.PostForm("name") key, _ := c.GetPostForm("key") fmt.Print(name, key) }) g.Run(":8080") }
name := c.PostForm("name") 传空值或者不传 默认打印都是空;不好区分
key, _ := c.GetPostForm("key")传空值或者不传 _ 空值是true,不传是false
3.4 文件上传
文件上传及路径存储
package main import ( "fmt" "github.com/gin-gonic/gin" "io" "os" ) func main() { g := gin.Default() g.POST("index", func(c *gin.Context) { file, err := c.FormFile("file") if err != nil { fmt.Println(err) return } //文件名称 filename := file.Filename //大小 size := file.Size fmt.Println(filename, size) openFile, _ := file.Open() bataByte, _ := io.ReadAll(openFile) err = os.WriteFile("xxx.jpg", bataByte, 0666) fmt.Println(err) }) g.Run(":8080") }
简单存储写法
err = c.SaveUploadedFile(file, "aaa.png") fmt.Println(err)
4、bind绑定器
4.1 参数绑定
4.1.1 查询参数
package main import ( "fmt" "github.com/gin-gonic/gin" ) func main() { g := gin.Default() g.GET("index", func(c *gin.Context) { type User struct { Name string `form:"name"` Age int `form:"age"` } var user User err := c.ShouldBindQuery(&user) fmt.Println(err, user) }) g.Run(":8080") }
访问路径 http://127.0.0.1:8080/index?name=段段&age=30
type User struct { Name string `form:"name"` Age int `form:"age"` }
c.ShouldBindQuery(&user) 查询参数
form:"name" 之间不能有空格
4.1.2 路径参数
package main import ( "fmt" "github.com/gin-gonic/gin" ) func main() { g := gin.Default() g.GET("index/:name/:age", func(c *gin.Context) { type User struct { Name string `uri:"name"` Age int `uri:"age"` } var user User err := c.ShouldBindUri(&user) fmt.Println(err, user) }) g.Run(":8080") }
访问路径 http://127.0.0.1:8080/index/段段/30
uri:"name" 之间不能有空格
c.ShouldBindUri(&user) 路径参数
4.1.3 表单参数
package main import ( "fmt" "github.com/gin-gonic/gin" ) func main() { g := gin.Default() g.POST("index", func(c *gin.Context) { type User struct { Name string `form:"name"` Age int `form:"age"` } var user User err := c.ShouldBind(&user) fmt.Println(err, user) }) g.Run(":8080") }
c.ShouldBind(&user) 表单参数
请求
http://localhost:8080/index form-data
4.1.4 JSON参数
package main import ( "fmt" "github.com/gin-gonic/gin" ) func main() { g := gin.Default() g.POST("index", func(c *gin.Context) { type User struct { Name string `json:"name"` Age int `json:"age"` } var user User err := c.ShouldBind(&user) fmt.Println(err, user) }) g.Run(":8080") }
请求
http://localhost:8080/index { "name":"段段", "age":30 }
.....比如headers
4.2 bind规则校验
4.2.1 常用校验
// 不能为空,并且不能没有这个字段 required: 必填字段,如:binding:"required" // 针对字符串的长度 min 最小长度,如:binding:"min=5" max 最大长度,如:binding:"max=10" len 长度,如:binding:"len=6" // 针对数字的大小 eq 等于,如:binding:"eq=3" ne 不等于,如:binding:"ne=12" gt 大于,如:binding:"gt=10" gte 大于等于,如:binding:"gte=10" lt 小于,如:binding:"lt=10" lte 小于等于,如:binding:"lte=10" // 针对同级字段的 eqfield 等于其他字段的值,如:PassWord string `binding:"eqfield=Password"` nefield 不等于其他字段的值 - 忽略字段,如:binding:"-"
4.2.2 内置校验
// 枚举 只能是red 或green oneof=red green // 字符串 contains=fengfeng // 包含fengfeng的字符串 excludes // 不包含 startswith // 字符串前缀 endswith // 字符串后缀 // 数组 dive // dive后面的验证就是针对数组中的每一个元素 // 网络验证 ip ipv4 ipv6 uri url // uri 在于I(Identifier)是统一资源标示符,可以唯一标识一个资源。 // url 在于Locater,是统一资源定位符,提供找到该资源的确切路径 // 日期验证 1月2号下午3点4分5秒在2006年 datetime=2006-01-02
4.2.3 校验代码样例
package main import ( "fmt" "github.com/gin-gonic/gin" ) func main() { g := gin.Default() g.POST("index", func(c *gin.Context) { type User struct { // binding:"required" 非空校验;,min=5 最小5位字符串 ;校验多个逗号分割 Name string `json:"name" binding:"required,min=5"` Age int `json:"age"` } var user User err := c.ShouldBind(&user) fmt.Println(err, user) }) g.Run(":8080") }
"required" 非空校验;,min=5 最小5位字符串 ;校验多个逗号分割
Name string json:"name" binding:"required,min=5"
自定义校验中文校验返回.....

GitCode 天启AI是一款由 GitCode 团队打造的智能助手,基于先进的LLM(大语言模型)与多智能体 Agent 技术构建,致力于为用户提供高效、智能、多模态的创作与开发支持。它不仅支持自然语言对话,还具备处理文件、生成 PPT、撰写分析报告、开发 Web 应用等多项能力,真正做到“一句话,让 Al帮你完成复杂任务”。
更多推荐
所有评论(0)