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()
   }
}
相关推荐
Tony Bai2 小时前
再见,丑陋的 container/heap!Go 泛型堆 heap/v2 提案解析
开发语言·后端·golang
念何架构之路5 小时前
Go进阶之panic
开发语言·后端·golang
先跑起来再说5 小时前
Git 入门到实战:一篇搞懂安装、命令、远程仓库与 IDEA 集成
ide·git·后端·elasticsearch·golang·intellij-idea
Aftery的博客5 小时前
Xcode运行报错:SDK does not contain ‘libarclite‘ at the path
macos·cocoa·xcode
Tony Bai13 小时前
“Go 2,请不要发生!”:如果 Go 变成了“缝合怪”,你还会爱它吗?
开发语言·后端·golang
灰子学技术1 天前
go response.Body.close()导致连接异常处理
开发语言·后端·golang
源代码•宸1 天前
大厂技术岗面试之谈薪资
经验分享·后端·面试·职场和发展·golang·大厂·职级水平的薪资
有代理ip2 天前
Python 与 Golang 爬虫的隐藏优势
爬虫·python·golang
天远云服2 天前
天远车辆过户查询API微服务实战:用Go语言构建高性能车况溯源系统
大数据·微服务·架构·golang
女王大人万岁2 天前
Go标准库 sync 详解
服务器·开发语言·后端·golang