文章首发于: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() 	 }
   |