Gin入门 | 青训营笔记

54 阅读3分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第5天

处理请求的方式

//默认在8080端口
	r := gin.Default()
	//传入路径,对应的响应的函数
        //GET/POST/DELETE/PUT
	r.GET("/hello", sayhello)
	r.Run(":9090")

返回json

向json中传入数据的方式有多种。

func sayhello(c *gin.Context) {
//方法1:使用map
        data := map[string]interface{}
//方法2:使用gin自定义的集合H,一种快速的无需指明类型的map
//data:= gin.H{"name":"小明",}

//方法3:使用自定义的结构体,结构体属性必须大写或使用标签注明(类似GORM标签注明字段),否则会出现序列化的问题。
//data: = user{"小明"}
//参数为状态码,数据
	c.JSON(http.StatusOK, data)
}

获取请求参数

跟请求像相关的参数往往都要从参数中 *gin.Context中获取。 例: localhost:8080/web?query=小明&age=18

r=c.Default()
r.GET("/web", response)

//获取参数
func response(c *gin.Context){
name1:=c.Query("query")
//DefaultQuery可以在取不到参数时使用默认值
name2:=c.DefaultQuery("query","默认名称")
//GetQuery函数有两个返回值,第一个为取参数结果,第二个为一个布尔值.取不到值时会返回false。
name,ok := c.GetQuery("query")

}

获取form表单的参数

name:=c.PostForm("username")
password=c.PostForm("password")

与DefaultQuery()类似,获取表单参数同样有DefaultPostForm()和GetPostForm()的方式。

获取URI路径参数

例如: localhost:8080/male/jack 对应的响应方式:

r.GET("/:sex/:name"func (c *gin.Context){
    name := c.Param("name")
    key := c.Param("age")
})

参数的映射

利用ShoudBind()方法绑定给结构体直接赋值,结构体中属性要大写并且用标签注明对应参数名。

package main

import (
   "fmt"
   "github.com/gin-gonic/gin"
   "net/http"
)
type UserInfo struct {
   Username string `form:"username" json:"username"`
   Password string `form:"password" json:"username"`
}
func main() {
   r := gin.Default()

   r.POST("/form", func(c *gin.Context) {
      var u UserInfo
      // 参数绑定
      err := c.ShouldBind(&u)
      if err != nil {
         c.JSON(http.StatusBadRequest, gin.H{
            "error: ": err.Error(),
         })
      } else {
         fmt.Println("%#v\n", u)
         c.JSON(http.StatusOK, gin.H{
            "status": "ok",
         })
      }
   })

   r.Run()
}

文件上传

//从form表单中获取文件
file,err :=c.FormFile("image")
if err!=nil{
    //错误处理
}else{
    //保存文件到本地
    dst:=path.Join("./",file.Filename)
    c.SaveUploadedFile(file,dst)
}

//多个文件上传时,将c.FormFile()函数换为:
//res即为存有文件的集合。
f, err := c.MultipartForm()
res = f.File["files"]

请求重定向

HTTP重定向

func main() {
   r := gin.Default()
   r.GET("/baidu", func(c *gin.Context) {
      c.Redirect(http.StatusMovedPermanently, "http://www.sogo.com")
   })
   r.Run(":8080")
}

路由重定向

func main() {
   r := gin.Default()
   r.GET("/a", func(c *gin.Context) {
      //把请求的地址设为/b
      c.Request.URL.Path = "/b"
      r.HandleContext(c)
   })

   r.GET("/b", func(c *gin.Context) {
   //处理不存在的请求地址可以使用r.NoRoute()
   })
   r.Run(":8080")
}

路由组

路由组即为几个请求提供公共的前缀。类似于java在controller上注释的请求路径。

v1 := router.Group("/v1") { 
    v1.POST("/login", loginEndpoint) 
    v1.POST("/submit", submitEndpoint) 
    v1.POST("/read", readEndpoint) 
}

中间件

golang中的中间件类似于Java中拦截器的概念,可以对一些广泛使用的功能做出实现,如日志记录,权限验证等等。

定义一个中间件

func m1(c *gin.Context) {
   fmt.Println("m1执行")
   //调用后续中间件
   c.Next()
   //c.Abort() 阻止后续中间件运行
   fmt.Println("m1结束")
}

添加中间件到控制器中

方式1:可以在路由里直接添加作为函数,只对该路由有效,同时决定了调用的顺序。 方式2:通过r.Use()的方法进行全局设置。 方式3:可以同时向路由组中注册中间件。

func main() {
   r := gin.Default()
   //r.Use(m1)
   r.GET("/user", m1, func(c *gin.Context) {
   })
   r.Run(":8080")
}

常用中间件写法

func authMiddleware(doCheck bool) gin.HandlerFunc {
   //一些准备工作 如连接数据库
   return func(c *gin.Context) {
      if doCheck {
         //一些其他逻辑
         c.Next()
         
      } else {
         c.Abort()
      }
   }
}