文章目录
获取参数
路径传参
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()
}
}