文章首发于:clawhub.club
框架的使用对于敏捷开发来说是非常重要的,虽然有不要重复造轮子的老话,但是在使用框架的同时一定要学习人家的思想与实现方式,免得发生没了框架就不会写代码的境地。
Gin的github地址:
https://github.com/gin-gonic/gin
中文文档地址:
https://gin-gonic.com/zh-cn/docs/
学习例子
1 hello word
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import ( "gopkg.in/gin-gonic/gin.v1" "net/http" )
func main(){
router := gin.Default()
router.GET("/", func(c *gin.Context) { c.String(http.StatusOK, "Hello World") }) router.Run(":8000") }
|
2 GET请求
1 2 3 4 5 6 7 8
| func main(){ router := gin.Default()
router.GET("/user/:name", func(c *gin.Context) { name := c.Param("name") c.String(http.StatusOK, "Hello %s", name) }) }
|
3简单的post请求
1 2 3 4 5 6 7 8 9 10 11 12 13
| router.POST("/form_post", func(c *gin.Context) { message := c.PostForm("message") nick := c.DefaultPostForm("nick", "anonymous")
c.JSON(http.StatusOK, gin.H{ "status": gin.H{ "status_code": http.StatusOK, "status": "ok", }, "message": message, "nick": nick, }) })
|
4 PUT 请求
1 2 3 4 5 6 7 8 9 10
| router.PUT("/post", func(c *gin.Context) { id := c.Query("id") page := c.DefaultQuery("page", "0") name := c.PostForm("name") message := c.PostForm("message") fmt.Printf("id: %s; page: %s; name: %s; message: %s \n", id, page, name, message) c.JSON(http.StatusOK, gin.H{ "status_code": http.StatusOK, }) })
|
5上传文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| router.POST("/upload", func(c *gin.Context) { name := c.PostForm("name") fmt.Println(name) file, header, err := c.Request.FormFile("upload") if err != nil { c.String(http.StatusBadRequest, "Bad request") return } filename := header.Filename
fmt.Println(file, err, filename)
c.String(http.StatusCreated, "upload successful") })
|
6 批量上传文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| router.POST("/multi/upload", func(c *gin.Context) { err := c.Request.ParseMultipartForm(200000) if err != nil { log.Fatal(err) }
formdata := c.Request.MultipartForm files := formdata.File["upload"] for i := range files { file, err := files[i].Open() filename := files[i].Filename fmt.Println(file, err, filename) defer file.Close() if err != nil { log.Fatal(err) } c.String(http.StatusCreated, "upload successful")
}
})
|
####7 c.HTML模板
1 2 3 4
| router.LoadHTMLGlob("G:\\GO\\src\\go-study\\src\\templates/*") router.GET("/upload", func(c *gin.Context) { c.HTML(http.StatusOK, "upload.html", gin.H{}) })
|
####8 c.BindJSON和c.BindWith
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| router.POST("/login", func(c *gin.Context) { var user User var err error contentType := c.Request.Header.Get("Content-Type")
switch contentType { case "application/json": err = c.BindJSON(&user) case "application/x-www-form-urlencoded": err = c.BindWith(&user, binding.Form) }
if err != nil { fmt.Println(err) log.Fatal(err) }
c.JSON(http.StatusOK, gin.H{ "user": user.Username, "passwd": user.Passwd, "age": user.Age, })
})
|
9 自动Bind
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| router.POST("/login", func(c *gin.Context) { var user User
err := c.Bind(&user) if err != nil { fmt.Println(err) log.Fatal(err) }
c.JSON(http.StatusOK, gin.H{ "username": user.Username, "passwd": user.Passwd, "age": user.Age, })
})
|
10 c.JSON与c.XML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| router.GET("/render", func(c *gin.Context) { contentType := c.DefaultQuery("content_type", "json") if contentType == "json" { c.JSON(http.StatusOK, gin.H{ "user": "rsj217", "passwd": "123", }) } else if contentType == "xml" { c.XML(http.StatusOK, gin.H{ "user": "rsj217", "passwd": "123", }) }
})
|
11 重定向
1 2 3 4
| router.GET("/redict/google", func(c *gin.Context) { c.Redirect(http.StatusMovedPermanently, "https://google.com") })
|
12 路由分组
1 2 3 4 5 6 7 8 9 10 11 12
| v1 := router.Group("/v1")
v1.GET("/login", func(c *gin.Context) { c.String(http.StatusOK, "v1 login") })
v2 := router.Group("/v2")
v2.GET("/login", func(c *gin.Context) { c.String(http.StatusOK, "v2 login") })
|
13 middleware中间件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| router.Use(MiddleWare()) { router.GET("/middleware", func(c *gin.Context) { request := c.MustGet("request").(string) req, _ := c.Get("request") c.JSON(http.StatusOK, gin.H{ "middile_request": request, "request": req, }) }) } router.GET("/before", MiddleWare(), func(c *gin.Context) { request := c.MustGet("request").(string) c.JSON(http.StatusOK, gin.H{ "middile_request": request, }) }) router.GET("/auth/signin", func(c *gin.Context) { cookie := &http.Cookie{ Name: "session_id", Value: "123", Path: "/", HttpOnly: true, } http.SetCookie(c.Writer, cookie) c.String(http.StatusOK, "Login successful") })
router.GET("/home", AuthMiddleWare(), func(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"data": "home"}) })
func AuthMiddleWare() gin.HandlerFunc { return func(c *gin.Context) { if cookie, err := c.Request.Cookie("session_id"); err == nil { value := cookie.Value fmt.Println(value) if value == "123" { c.Next() return } } c.JSON(http.StatusUnauthorized, gin.H{ "error": "Unauthorized", }) c.Abort() return } }
func MiddleWare() gin.HandlerFunc { return func(c *gin.Context) { fmt.Println("before middleware") c.Set("request", "clinet_request") c.Next() fmt.Println("before middleware") } }
|
14 异步协程
1 2 3 4 5
| router.GET("/sync", func(c *gin.Context) { time.Sleep(5 * time.Second) log.Println("Done! in path" + c.Request.URL.Path) })
|
15 自定义router
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| router.GET("/async", func(c *gin.Context) { cCp := c.Copy() go func() { time.Sleep(5 * time.Second) log.Println("Done! in path" + cCp.Request.URL.Path) }() }) s := &http.Server{ Addr: ":8000", Handler: router, ReadTimeout: 10 * time.Second, WriteTimeout: 10 * time.Second, MaxHeaderBytes: 1 << 20, } s.ListenAndServe() }
|