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()
   }
}
相关推荐
Clarence Liu3 小时前
AI Agent开发(2) - 深入解析 A2A 协议与 Go 实战指南
开发语言·人工智能·golang
小胖红5 小时前
Xcode 打包失败 处理
ide·macos·xcode
源代码•宸10 小时前
Golang原理剖析(defer、defer面试与分析)
开发语言·经验分享·后端·面试·golang·defer·开放编码
且去填词11 小时前
三色标记法与混合写屏障:Go GC 垃圾回收全流程解析
开发语言·算法·golang·三色标记法·gogc·屏障技术
源代码•宸13 小时前
Golang原理剖析(interface)
服务器·开发语言·后端·golang·interface·type·itab
王家视频教程图书馆13 小时前
go语言 gin grom jwt 登陆token验证 增删改查 分页 完整 图书管理系统
gin
汪碧康14 小时前
一文掌握k8s容器的资源限制
docker·云原生·容器·golang·kubernetes·k8s·xkube
PKWjiMrlayO14 小时前
LabView源码与三菱FX编程口协议通讯的实现方案
xcode
moxiaoran57531 天前
Go语言的错误处理
开发语言·后端·golang
CTO Plus技术服务中2 天前
一栈式、系统性的C、C++、Go、网络安全、Linux运维开发笔记和面试笔记
c++·web安全·golang