gin 框架(二) | 青训营笔记

153 阅读2分钟

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

概述

  • 获取参数 get/post
  • 上传文件

获取参数

get方法

http://localhost:8080/hello?name=Jone

func main() {
	fmt.Println("Starting server...")
	defer fmt.Println("Server stopped.")
	r := gin.Default()
	r.GET("/hello", func(c *gin.Context) {
		// name := c.Query("name")
		// name := c.DefaultQuery("name", "Guest")
		name, ok := c.GetQuery("name")
		if !ok {
			name = "Guest"
		}
		c.JSON(http.StatusOK, name)
	})
	r.Run() // listen and serve on
}

获取参数的方法有三种

  • Query 只查询
  • DefaultQuery 可以设置默认值
  • GetQuery 会返回两个参数,string boolean

form 表单

func main() {
	r := gin.Default()
	r.LoadHTMLFiles("./templates/index.tmpl")

	r.GET("/login", func(c *gin.Context) {
		c.HTML(http.StatusOK, "index.tmpl", nil)
	})

	r.POST("/login", func(c *gin.Context) {
		username := c.PostForm("username")
		password := c.PostForm("password")
		c.JSON(200, gin.H{"username": username, "password": password})
	})
	r.Run() // listen and serve on
}

post获取参数同样有三种,使用Get

  • PostForm
  • DefaultPostForm
  • GetPostForm

获取path参数

http://localhost:8080/user/Jone/18

func main() {
	r := gin.Default()

	r.GET("/user/:name/:age", func(c *gin.Context) {
		username := c.Param("name")
		age := c.Param("age")
		c.JSON(http.StatusOK, gin.H{
			"username": username,
			"age":      age,
		})
	})

	r.Run() // listen and serve on
}

低版本一些情况下会有错误(如下),但是新版本已经做了改善

r.GET("/:name/:age", func(c *gin.Context) {...})
r.GET("/blog/:year/:month", func(c *gin.Context) {...})

绑定参数

通过结构体的形式获取参数

type UserInfo struct {
	Name string `form:"name" json:"name" binding:"required"`
	Age  int    `form:"age" json:"age" binding:"required"`
}

GET

func main() {
	r := gin.Default()

	r.GET("/user", func(c *gin.Context) {
		var u UserInfo
		err := c.ShouldBind(&u)
		if err != nil {
			c.JSON(http.StatusOK, gin.H{"error": err})
			return
		}
		fmt.Printf("%#v\n", u)
		c.JSON(http.StatusOK, gin.H{
			"name": u.Name,
			"age":  u.Age,
		})
	})

	r.Run() // listen and serve on
}

POST(form 或 JSON)

func main() {
	r := gin.Default()
	
	r.POST("/login", func(c *gin.Context) {
		var u UserInfo
		err := c.ShouldBind(&u)
		if err != nil {
			c.JSON(http.StatusOK, gin.H{"error": err})
			return
		}
		fmt.Printf("%#v\n", u)
		c.JSON(http.StatusOK, gin.H{
			"name": u.Name,
			"age":  u.Age,
		})
	})

	r.Run() // listen and serve on
}

可以看出使用绑定参数,就可以以一种十分方便的格式去处理数据。

上传文件

只展示如何上传单文件。

<form action="/upload" method="post" enctype="multipart/form-data">
  <input type="file" name="f1" />
  <input type="submit" value="上传" />
</form>

注意表单属性 enctype="multipart/form-data"

r.POST("/upload", func(c *gin.Context) {
        //从请求中获取文件
        file, err := c.FormFile("f1")
        if err != nil {
                c.JSON(http.StatusOK, gin.H{"status": "fail", "message": err.Error()})
                return
        }
        // 如果不存在upload文件夹创建
        if _, err := os.Stat("./upload"); os.IsNotExist(err) {
                os.Mkdir("./upload", os.ModePerm)
        }
        // 保存文件
        dst := path.Join("./upload", file.Filename)
        c.SaveUploadedFile(file, dst)
        c.JSON(http.StatusOK, gin.H{"status": "success", "message": "上传成功"})
})
  • 获取文件:c.FormFile(input_name) arg:input元素的 name 值
  • 保存文件:c.SaveUploadedFile(file, dst) arg1:文件流、arg2:保存地址

参考