<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Gin框架系列02:路由與參數

      回顧

      上一節我們用Gin框架快速搭建了一個GET請求的接口,今天來學習路由和參數的獲取。

      請求動詞

      熟悉RESTful的同學應該知道,RESTful是網絡應用程序的一種設計風格和開發方式,每一個URI代表一種資源,客戶端通過POST、DELETEPUTGET四種請求方式來對資源做增刪改查的操作。

      同樣的,Gin框架給我們提供的除這4種動詞外,還有PATCHOPTION、HEAD等,詳細內容可以查看rentergroup.go文件的IRoutes接口。

      type IRoutes interface {
      	Use(...HandlerFunc) IRoutes
      
      	Handle(string, string, ...HandlerFunc) IRoutes
      	Any(string, ...HandlerFunc) IRoutes
      	GET(string, ...HandlerFunc) IRoutes
      	POST(string, ...HandlerFunc) IRoutes
      	DELETE(string, ...HandlerFunc) IRoutes
      	PATCH(string, ...HandlerFunc) IRoutes
      	PUT(string, ...HandlerFunc) IRoutes
      	OPTIONS(string, ...HandlerFunc) IRoutes
      	HEAD(string, ...HandlerFunc) IRoutes
      
      	StaticFile(string, string) IRoutes
      	Static(string, string) IRoutes
      	StaticFS(string, http.FileSystem) IRoutes
      }
      

      因為RenterGroup實現了IRoutes定義的所有請求動詞,而且gin.Default返回的Engine類型繼承了RenterGroup,所以使用起來非常簡單,只需要通過gin.Default實例化對象,接下來所有的路由操作都通過該對象使用即可。

      file

      func main() {
      	router := gin.Default()
      	router.POST("/article", func(c *gin.Context) {
      		c.String(200, "article post")
      	})
      	router.DELETE("/article", func(c *gin.Context) {
      		c.String(200, "article delete")
      	})
      	router.PUT("/article", func(c *gin.Context) {
      		c.String(200, "article put")
      	})
      	router.GET("/article", func(c *gin.Context) {
      		c.String(200, "article get")
      	})
      	router.Run()
      }
      

      請求動詞的第一個參數是請求路徑,第二個參數是用于邏輯處理的函數,可以是匿名的或是其他地方定義的函數名。不同的請求動詞可以定義相同的路徑,只需要切換動詞就可以進入對應的處理邏輯。

      curl -X PUT http://localhost:8080/article
      curl -X POST http://localhost:8080/article
      curl -X GET http://localhost:8080/article
      curl -X DELETE http://localhost:8080/article
      

      路由參數

      GET請求有兩種,一種是在URL后加上?name=pingye,這種是有參數名的,另一種是在路徑中直接加上參數值/article/1,這種沒有參數名,需要在代碼中解析參數。

      protocol://hostname:[port]/path/[query]#fragment
      

      我們先來看路由攜帶參數值的玩法,這里有一道題,怎么利用Gin獲取下面鏈接的參數值1。

      file

      實現方式非常簡單,只需要在路由中設置好占位符:id,冒號為占位符的標志,冒號后面的參數名可以自定義,Gin會將路由與請求地址進行匹配,若匹配成功會將1賦值為占位符:id,只需調用c.Param就可以獲取id的值。

      router.GET("/article/:id", func(c *gin.Context) {
        id := c.Param("id")
        c.String(200, id)
      })
      

      但是,:id占位符會存在一個問題,如果id參數值傳空就會有404的錯誤提示。

      file

      于是Gin提供了另一種占位符*id,使用它就可以達到取空值的目的。

      router.GET("/article/*id", func(c *gin.Context) {
        id := c.Param("id")
        c.String(200, id)
      })
      

      普通參數

      除了路由攜帶參數值外,接下來看比較傳統的GET傳參方式。

      http://localhost:8080/welcome?firstname=Jane&lastname=Doe
      

      可以通過c.Queryc.DefaultQuery方法獲取問號后的參數。

      router.GET("/welcome", func(c *gin.Context) {
         firstname := c.DefaultQuery("firstname", "pingyeaa")
         lastname := c.Query("lastname")
         c.String(200, firstname+" "+lastname)
      })
      

      這兩者最終都調用了GetQuery方法,唯一的區別是DefaultQuery做了默認值處理。

      func (c *Context) DefaultQuery(key, defaultValue string) string {
      	if value, ok := c.GetQuery(key); ok {
      		return value
      	}
      	return defaultValue
      }
      
      func (c *Context) Query(key string) string {
      	value, _ := c.GetQuery(key)
      	return value
      }
      

      表單參數

      從HTML提交過來的表單form內容同樣也可以輕松獲取。

      router.POST("/form_post", func(c *gin.Context) {
        message := c.PostForm("message")
        nick := c.DefaultPostForm("nick", "anonymous")
      
        c.JSON(200, gin.H{
          "status":  "posted",
          "message": message,
          "nick":    nick,
        })
      })
      
      curl -d "message=pingye" http://localhost:8080/form_post
      {"message":"pingye","nick":"anonymous","status":"posted"}
      

      數組類型參數

      有時候(例如復選框)前端頁面會傳來數組類型的值,這種類型name相同,但存儲的內容不同。

      POST /post?ids[a]=1234&ids[b]=hello HTTP/1.1
      Content-Type: application/x-www-form-urlencoded
      

      依然是一個QueryMap方法就搞定,該方法默認返回map類型。

      router.GET("/post", func(c *gin.Context) {
        ids := c.QueryMap("ids")
        c.String(200, ids["a"]+" "+ids["b"])
      })
      
      curl http://localhost:8080/post?ids[a]=pingye&ids[b]=hehe
      pingye hehe
      

      文件上傳

      一般情況下,文件上傳會由前端直接傳給云存儲服務商,比如阿里云、七牛云等,比較少的場景會傳給自己的服務器。為了避免書到用時方恨少的情況發生,我們來了解一下。

      Gin提供了FormFile方法獲取文件流,這個方法返回了一個FileHeader類型的變量,可以調用Filename屬性來查看文件名。

      type FileHeader struct {
         Filename string
         Header   textproto.MIMEHeader
         Size     int64
      
         content []byte
         tmpfile string
      }
      
      router.POST("/upload", func(c *gin.Context) {
        file, _ := c.FormFile("file")
        c.String(200, file.Filename)
      })
      

      通過curl請求接口,可以看到輕松獲取文件名稱。

      curl -X POST http://localhost:8080/upload \
        -F "file=@/Users/enoch/Downloads/IMG_9216.JPG" \
        -H "Content-Type: multipart/form-data"
      IMG_9216.JPG
      

      當然不止可以拿到文件名,我們還可以使用SaveUploadedFile方法將文件保存到某個地方,文件保存時要確保有目標目錄的操作權限。

      router.POST("/upload", func(c *gin.Context) {
      		file, _ := c.FormFile("file")
      		c.String(200, file.Filename)
      		err := c.SaveUploadedFile(file, "/Users/enoch/Desktop/ab.png")
      		if err != nil {
      			c.String(500, err.Error())
      		}
      })
      

      路由分組

      當接口發生重大變更(比如入參出參)時,考慮到向下兼容,一般會新增一個接口,但是又希望新接口的名稱顯而易見地看出是老接口的升級版,那么就可以在接口名前加上版本號v1/article這種形式。

      v1 := r.Group("v1")
      {
        v1.POST("/login", func(c *gin.Context) {
          c.String(200, "v1/login")
        })
        v1.POST("/submit", func(c *gin.Context) {
          c.String(200, "v1/submit")
        })
      }
      
      v2 := r.Group("v2")
      {
        v2.POST("/login", func(c *gin.Context) {
          c.String(200, "v2/login")
        })
        v2.POST("/submit", func(c *gin.Context) {
          c.String(200, "v2/submit")
        })
      }
      
      curl -X POST http://localhost:8080/v1/login
      curl -X POST http://localhost:8080/v2/login
      

      Go語言庫代碼示例,歡迎star
      https://github.com/pingyeaa/golang-examples

      感謝大家的觀看,如果覺得文章對你有所幫助,歡迎關注公眾號「平也」,聚焦Go語言與技術原理。
      關注我

      posted @ 2020-04-08 15:04  MARIOOW  閱讀(4019)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 久久视频在线视频| 亚洲黄色第一页在线观看| 免费观看在线A级毛片| 日韩一区二区三区女优丝袜| 日韩av爽爽爽久久久久久| a男人的天堂久久a毛片| 国产精品无码dvd在线观看| 亚洲欧美综合精品成人网站| 中文午夜乱理片无码| 亚洲免费观看在线视频| 麻豆国产97在线 | 欧美| 深夜视频国产在线观看| 国产福利萌白酱在线观看视频 | 亚洲AV成人片不卡无码| 麻豆国产AV剧情偷闻女邻居内裤 | 天堂网亚洲综合在线| 四虎永久免费很黄的视频| 欧美乱妇狂野欧美在线视频| 中文字幕av日韩有码| 亚洲精品电影院| 粗大挺进朋友人妻淑娟| 博罗县| 久久毛片少妇高潮| 亚洲欧美日韩综合一区二区| 国产精品久久露脸蜜臀| 精品一区二区不卡免费| 色婷婷狠狠久久综合五月| 久久欧洲精品成av人片| 无套内谢极品少妇视频| 精品免费国产一区二区三区四区介绍| аⅴ天堂国产最新版在线中文| 综合人妻久久一区二区精品| 熟妇的奶头又大又长奶水视频| 久久精品一偷一偷国产| 精品一区二区三区四区色| 99久久99久久精品免费看蜜桃| 国产精品制服丝袜白丝| 日韩午夜福利片段在线观看| 亚洲欧美一区二区成人片| 超碰伊人久久大香线蕉综合| 久久精品熟妇丰满人妻久久|