Go: Gin的用法

文章目录

获取参数

路径传参

go 复制代码
func main() {
	e := gin.Default()
	e.GET("/findUser/:username/:userid", FindUser)

	server := e.Run(":8080")
	log.Fatalln(server)
}

func FindUser(context *gin.Context) {
	username := context.Param("username")
	userid := context.Param("userid")
	context.String(http.StatusOK, username, userid)
}

url 传参(查询字符串)

普通解析:

go 复制代码
func test2() {
	e := gin.Default()
	e.GET("/findUser", FindUser2)
	log.Fatalln(e.Run(":8080"))
}

func FindUser2(c *gin.Context) {
	username := c.DefaultQuery("username", "defaultUser")
	userid := c.Query("userid")
	c.String(http.StatusOK,username,userid)
}

参数转成结构体:

go 复制代码
func test2() {
	e := gin.Default()
	e.GET("/findUser", FindUserToStruct)
	log.Fatalln(e.Run(":8080"))
}

func FindUserToStruct(context *gin.Context) {
	var query FindUserQuery
	if err := context.ShouldBindQuery(&query); err != nil {
		return
	}
	fmt.Println(query)
}

post json传参

普通解析:

go 复制代码
func test3() {
	e := gin.Default()
	e.POST("/findUser", FindUser3)
	log.Fatalln(e.Run(":8080"))
}

func FindUser3(context *gin.Context) {
	username := context.PostForm("username")
	password := context.PostForm("password")
	context.String(http.StatusOK, username, password)
}

参数转成结构体:

go 复制代码
func test3() {
	e := gin.Default()
	e.POST("/findUser", PostFindUserToStruct)
	log.Fatalln(e.Run(":8080"))
}

func PostFindUserToStruct(context *gin.Context) {
	var body PostFindUserBody
	if err := context.BindJSON(&body); err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(body)
}

type PostFindUserBody struct {
	Name string `json:"username"`
	Age  int    `json:"age"`
}

数据校验

必填类:

go 复制代码
标签	说明
required	必填字段,不能为空
omitempty	可空,空则跳过后续校验
示例:
Name string `json:"name" validate:"required"`
Age  int    `json:"age" validate:"omitempty,min=1"`

字符串长度校验
标签	说明
min=数字	最小长度
max=数字	最大长度
len=数字	固定长度
示例:
Password string `validate:"min=6,max=18"`
Code     string `validate:"len=6"`

数值范围校验
标签	说明
gt=数字	大于
lt=数字	小于
gte=数字	大于等于
lte=数字	小于等于
示例:
Age int `validate:"gte=1,lte=150"`

Gin 中启用 validator
Gin 默认集成 validator,只需要:
if err := c.ShouldBind(&req); err != nil {
    errs := err.(validator.ValidationErrors)
    fmt.Println(errs)
}

例:

go 复制代码
func test4() {
	e := gin.Default()
	e.POST("/testValidator", Register)
	log.Fatalln(e.Run(":8080"))
}

type LoginUser struct {
	Username string `binding:"required"  json:"username" form:"username" uri:"username"`
	Password string `binding:"required" json:"password" form:"password" uri:"password"`
}

func Register(ctx *gin.Context) {
	newUser := &LoginUser{}
	if err := ctx.ShouldBind(newUser); err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println(*newUser)
}

数据响应

go 复制代码
func FindUser3(context *gin.Context) {
	username := context.PostForm("username")
	password := context.PostForm("password")
	context.String(http.StatusOK, username, password)
}

// JSON方式进行渲染
func (c *Context) JSON(code int, obj any) 

接口分组

go 复制代码
func test5() {
	e := gin.Default()
	
	v1 := e.Group("v1");
	{
		v1.POST("/login", func(c *gin.Context) {})
		v1.POST("/signup", func(c *gin.Context) {})
	}
	v2 := e.Group("v2");
	{
		v2.POST("/v2/login", func(c *gin.Context) {})
		v2.POST("/v2/signup", func(c *gin.Context) {})
	}
}

404路由:匹配不到接口的默认响应

go 复制代码
func test6() {
	e := gin.Default()

	e.NoRoute(func(context *gin.Context) { // 这里只是演示,不要在生产环境中直接返回HTML代码
		context.String(http.StatusNotFound, "查无此接口")
	})
	e.Run(":8080")
}

405路由:请求方法错误

默认情况下,Gin 对 "方法不匹配" 的行为是:

返回 404 Not Found而不是 405,需要开启e.HandleMethodNotAllowed = true

go 复制代码
func test7() {
	e := gin.Default()
	e.HandleMethodNotAllowed = true
	e.GET("/fs", func(c *gin.Context) {})
	// 注册处理器
	e.NoMethod(func(context *gin.Context) {
		context.String(http.StatusMethodNotAllowed, "method not allowed")
	})
	e.Run(":8080")
}

用post访问/fs,则会返回method not allowed

中间件:类似Java的拦截器

全局中间件

全局中间件即作用范围为全局,整个系统所有的请求都会经过此中间件。

go 复制代码
func test8() {
	e := gin.Default()
	e.Use(func(c *gin.Context) {
		fmt.Println("hello", c.Request.RequestURI)
	})
	e.GET("/fs", func(c *gin.Context) {})
	e.Run(":8080")
}

局部中间件

go 复制代码
func test9() {
	e := gin.Default()
	e.Use(func(c *gin.Context) {
		fmt.Println("全局处理器")
	})

	v1 := e.Group("v1", func(c *gin.Context) {
		fmt.Println("v1处理器")
	})
	{
		v1.POST("/fs1", func(c *gin.Context) {})
		v1.POST("/fs2", func(c *gin.Context) {})
	}
	v2 := e.Group("v2")
	{
		v2.POST("/fs3", func(c *gin.Context) {})
		v2.POST("/fs4", func(c *gin.Context) {})
	}
	e.Run(":8080")
}

跨域处理

放到gin.Default().Use(CorsMiddle())即可

go 复制代码
func CorsMiddle() gin.HandlerFunc {
   return func(c *gin.Context) {
      method := c.Request.Method
      origin := c.Request.Header.Get("Origin")
      if origin != "" {
         // 生产环境中的服务端通常都不会填 *,应当填写指定域名
         c.Header("Access-Control-Allow-Origin", origin)
         // 允许使用的HTTP METHOD
         c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, UPDATE")
         // 允许使用的请求头
         c.Header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization")
         // 允许客户端访问的响应头
         c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Cache-Control, Content-Language, Content-Type")
         // 是否需要携带认证信息 Credentials 可以是 cookies、authorization headers 或 TLS client certificates 
         // 设置为true时,Access-Control-Allow-Origin不能为 *
         c.Header("Access-Control-Allow-Credentials", "true")
      }
      // 放行OPTION请求,但不执行后续方法
      if method == "OPTIONS" {
         c.AbortWithStatus(http.StatusNoContent)
      }
      // 放行
      c.Next()
   }
}
相关推荐
zs宝来了6 小时前
Go pprof 性能剖析:CPU、内存与锁分析
golang·go·后端技术
hrhcode7 小时前
【java工程师快速上手go】一.Go语言基础
java·开发语言·golang
LlNingyu7 小时前
Go 实现无锁环形队列:面向多生产者多消费者的高性能 MPMC 设计
开发语言·golang·队列·mpmc·数据通道
深挖派8 小时前
GoLand 2026.1 安装配置与环境搭建 (保姆级图文教程)
后端·golang·编辑器·go·goland
geovindu9 小时前
go: Factory Method Pattern
开发语言·后端·golang
Lucas_coding9 小时前
【语音相关ASR】FunASR 离线语音识别与FunASR热词优化
人工智能·语音识别·xcode
zs宝来了10 小时前
Go Context:上下文传播与取消机制
golang·go·源码解析·后端技术
GDAL10 小时前
为什么选择gin?
golang·gin
秋雨梧桐叶落莳11 小时前
【iOS】 AutoLayout初步学习
学习·macos·ios·objective-c·cocoa·xcode
non-action_pilgrim11 小时前
《小坦克大战小怪兽》小游戏实战四:基于 protoactor-go 的游戏服务器框架与状态持久化实战
服务器·游戏·golang