GO語言 gin框架 簡述

原文地址?基本路由 · Go語言中文文檔

一、簡介

? ??Gin是一個golang的輕量級web框架,性能不錯,API友好。

? ? Gin支持Restful風格的API,可以直接從URL路徑上接收api參數或者URL參數,也可是使用json或者表單 數據綁定的方式接收參數。

? ? Gin響應前端的方式,可以使用的方式包括 json、結構體、protobuff的、XML、YAML。

? ? Gin可以使用路由分組的方式管理API,支持api路徑重定向

? ? Gin的路由庫用的是 httprouter,路由節點的數據結構是壓縮字典樹,提高路由效率。

? ? Gin支持全局中間件和局部中間件,支持中間件分段邏輯的Next方法

? ? Gin支持cookie和Session的方法去識別和驗證客戶端。

? ? Gin支持 Air 實時監聽代碼文件自動重新編譯執行。

二、gin路由

1.?基本路由

????gin 框架中采用的路由庫是基于 httprouter 做的,是第三方HTTP路由包,特點高性能、可擴展

(1) 使用方式:

? ? ?New()函數生成了一個 Router對象 。

? ? ?GET()方法 或 POST()方法 注冊一個適配路徑的響應函數??

? ? ?將 Router對象 作為參數傳給 ListenAndServe()函數 啟動HTTP服務。

router := httprouter.New()
router.GET("/", handleFunc)
http.ListenAndServe(":8080", router)

(2)?httprouter?為常用的HTTP方法提供快捷使用方式:

? ? ?獲取:? func (r *Router) GET(path string, handle Handle)

? ? ?添加:? func (r *Router) POST(path string, handle Handle)

? ? ?修改:? func (r *Router) PUT(path string, handle Handle)

? ? ?刪除:? func (r *Router) DELETE(path string, handle Handle)

(3)?httprouter?包中對URL使用兩種匹配模式:

? ? ?形如/user/name的精確匹配

? ? ?形如/user/*name的匹配所有的模式

(4)?可以處理二級域名。先 根據域名獲取對應的Handler路由,然后調用分發機制去處理。

func main() {......//分別處理不同的二級域名hs := make(HostMap)hs["sub1.localhost:8080"] = userRouterhs["sub2.localhost:8080"] = dataRouter//一級域名:localhost,二級域名:sub1.localhosthttp.ListenAndServe(":8080", hs)
}type HostMap map[string]http.Handlerfunc (hs HostMap) ServeHTTP(w http.ResponseWriter, r *http.Request) {//先根據域名獲取對應的Handler路由,然后調用處理if handler := hs[r.Host]; handler != nil {handler.ServeHTTP(w, r)}
}
2.?Restful風格的API

? ??gin支持Restful風格的API,即: URL定位資源,用HTTP描述操作。例如:

(1) 獲取文章 /blog/getXxx Get blog/Xxx

(2) 添加 /blog/addXxx POST blog/Xxx

(3) 修改 /blog/updateXxx PUT blog/Xxx

(4) 刪除 /blog/delXxxx DELETE blog/Xxx

3.?API參數

? ? Api參數就是在Api地址上輸入的參數。

? ? 可以通過Context的Param方法來獲取API參數

func main() {r := gin.Default()r.GET("/user/:name/*action", func(c *gin.Context) {name := c.Param("name")action := c.Param("action")action = strings.Trim(action, "/") //截取/后面的內容c.String(http.StatusOK, name+" is "+action)})r.Run(":8000") //監聽8080端口
}

?在瀏覽器輸入:? ?http://localhost:8080/user/枯藤/doview,獲得name參數"枯藤",action參數 "doview"

4.?URL參數

? ?URL參數就是在用Get方式,在?后面輸入的參數。

? ?可以通過DefaultQuery()或Query()方法獲取URL參數

r.GET("/user", func(c *gin.Context) {name := c.DefaultQuery("name", "枯藤")    //name是參數名稱,枯藤是默認值c.String(http.StatusOK, fmt.Sprintf("hello %s", name))
})

?在瀏覽器輸入:? ?http://localhost:8080/user?name=烏鴉,獲得name參數"烏鴉"

5.?表單參數

(1) 表單傳輸為 post請求。http常見的傳輸格式:

? ? application/json

? ? application/x-www-form-urlencoded (默認)

? ? multipart/form-data

(2)?表單參數可以通過 PostForm() 方法獲取

r.POST("/form", func(c *gin.Context) {username := c.PostForm("username")password := c.PostForm("userpassword")c.String(http.StatusOK, fmt.Sprintf("username:%s,password:%s", username, password))
})
6.?上傳單個文件

(1) multipart/form-data格式用于文件上傳

(2) 通過 FormFile() 方法獲得文件對象?

r.POST("/upload", func(c *gin.Context) {file, err := c.FormFile("file")c.String(http.StatusOK, file.Filename)})
7.?上傳多個文件

(1) 上傳多個文件也是用 multipart/form-data格式

(2)?通過 MultipartForm() 方法獲得文件對象列表

r.POST("/upload", func(c *gin.Context) {form, err := c.MultipartForm()files := form.File["files"]    // 獲取所有圖片for _, file := range files {    // 遍歷所有圖片c.SaveUploadedFile(file, file.Filename)}
})
8.?routes group

??routes group(路由分組) 可以分組管理相同的URL。?

? ?如下代碼,v1和v2分別是兩個路由組。

func main() {r := gin.Default() //創建默認路由v1 := r.Group("/v1")    //路由組1{   // {} 是書寫規范v1.GET("/login", login)v1.GET("submit", submit)}v2 := r.Group("/v2")    //路由組2{v2.POST("/login", login)v2.POST("/submit", submit)}r.Run(":8000")
}
9.?路由原理

??httprouter使用的數據結構是壓縮字典樹。

??普通的字典樹:每個字母都建立一個路由節點

??壓縮字典樹:只對每個有效前綴建立路由節點。如下圖所示:

三、gin數據解析和綁定

? ? ?支持三種方式的數據解析,json、表單 和 url參數

1.?Json 數據解析和綁定

? ? ?使用 context 的?ShouldBindJSON 方法

type Login struct {User    string `json:"user"  binding:"required"`Pssword string `json:"password"  binding:"required"`
}func main() {r := gin.Default()r.POST("loginJSON", func(c *gin.Context) {// 聲明接收的變量var json Login// 將request的body中的數據,自動按照json格式解析到結構體if err := c.ShouldBindJSON(&json); err != nil {......}......})......
}
2.?表單數據解析和綁定

? ?使用 context 的 Bind?方法

type Login struct {User    string `form:"username" binding:"required"`Pssword string `form:"password" binding:"required"`
}func main() {r := gin.Default()r.POST("/loginForm", func(c *gin.Context) {var form Login// Bind()默認解析并綁定form格式// 根據請求頭中content-type自動推斷if err := c.Bind(&form); err != nil {......}......})......
}
3.?URI數據解析和綁定

? ?使用 context 的?ShouldBindUri 方法

type Login struct {User    string `uri:"user" xml:"user" binding:"required"`Pssword string `uri:"password" xml:"password" binding:"required"`
}func main() {r := gin.Default()r.GET("/:user/:password", func(c *gin.Context) {if err := c.ShouldBindUri(&login); err != nil {.......}.......}).......
}

四、gin 渲染

1.?各種數據格式的響應

(1) json 響應

c.JSON(200, gin.H{"message": "someJSON", "status": 200})

(2) 結構體 響應

var msg struct {Name    stringMessage string
}
msg.Name = "root"
msg.Message = "message"
c.JSON(200, msg)

(3) XML,YAML 響應

c.XML(200, gin.H{"message": "abc"})
c.YAML(200, gin.H{"name": "zhangsan"})

(4)?protobuf?響應

data := &protoexample.Test{Label: &label,Reps:  reps,
}
c.ProtoBuf(200, data)
2.?HTML模板渲染

? ?gin支持加載 HTML模板, 然后根據模板參數進行配置并返回相應的數據。

? ?本質上就是字符串替換。

func main() {r := gin.Default()r.LoadHTMLGlob("tem/*")    //加載模板文件r.GET("/index", func(c *gin.Context) {//index.html就是具體的模板文件c.HTML(http.StatusOK, "index.html", gin.H{"title": "我是測試", "ce": "123456"})})r.Run()
}
3. 重定向

? 可以使用 context 的??Redirect 方法進行重定向

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

??當客戶端請求 /redirect_me 時,服務器將重定向到 https://www.5lmh.com

4.?同步異步

??goroutine機制可以實現異步處理,但不應該使用原始上下文,必須使用它的只讀副本。

func main() {r := gin.Default()r.GET("/long_async", func(c *gin.Context) { copyContext := c.Copy()    // 需要拷貝一個副本go func() {    // 異步處理time.Sleep(3 * time.Second)log.Println("異步執行:" + copyContext.Request.URL.Path)}()})r.Run(":8000")
}

五、gin中間件

1.?全局中間件

? ??所有請求都經過此中間件。

? ? 實現代碼如下:

func MiddleWare() gin.HandlerFunc {......
}func main() {r := gin.Default()r.Use(MiddleWare())r.Run()
}
2.?Next()方法

? ? 當程序執行到context.Next時,會轉而先去執行具體的業務邏輯。

? ? 執行完業務邏輯處理函數之后,程序會再次回到context.Next處,繼續執行中間件后續的代碼。

func MiddleWare() gin.HandlerFunc {return func(c *gin.Context) {fmt.Println("中間件開始執行了")c.Next()    //轉去執行業務邏輯//業務邏輯執行完,返回此處,繼續執行中間件代碼.......fmt.Println("中間件執行完畢", status)}
}func main() {r := gin.Default()r.Use(MiddleWare())    // 注冊中間件r.GET("/ce", func(c *gin.Context) {......})r.Run()
}

? 解釋原文?Golang gin 中間件、context.Next函數_gin context.next-CSDN博客

3.?局部中間件

? ? 中間件只在具體某個路由生效,不使用 r.use() 定義的中間件。

func main() {r := gin.Default()//只在 /ce 的路由里使用局部中間件 PartMiddleWare()r.GET("/ce", PartMiddleWare(), func(c *gin.Context) { ......})r.Run()
}

??解釋原文?局部生效的中間件_如何使用局部中間件-CSDN博客

六、會話控制

?1. Cookie介紹

(1)?HTTP是無狀態協議,服務器不能記錄瀏覽器的訪問狀態,不能區分兩次請求是否由同一個客戶端發出。

(2)?Cookie 就是一段可以區分不同客戶端的信息,由服務器創建,發送給瀏覽器,瀏覽器保存。

(3)?瀏覽器向服務器發送請求時,都會同時將Cookie發送給服務器,服務器根據處理請求。

2.?Cookie的使用

? ?登錄時設置cookie,其他請求檢驗cookie,代碼如下:

func AuthMiddleWare() gin.HandlerFunc {return func(c *gin.Context) {//2.獲取cookie并校驗if cookie, err := c.Cookie("abc"); err == nil {if cookie == "123" {c.Next() //3.cookie檢驗通過,執行請求邏輯return}}......return}
}func main() {r := gin.Default()r.GET("/login", func(c *gin.Context) {c.SetCookie("abc", "123", 60, "/", "localhost", false, true) //1.登錄成功,設置cookiec.String(200, "Login success!")})......
}
3.?Cookie的缺點

(1)?不安全,明文,容易泄露信息

(2) 可以被瀏覽器禁用。

(3) 有數量限制。某些瀏覽器對某個域名的cookie有數量限制,大概50個。

4.?Sessions

(1) session和cookie 實現的目標是一致的,但實現的方法不同;

(2) session 是另一種記錄客戶狀態的機制,?不同的是 Cookie 保存在客戶端瀏覽器中,而 session保存在服務器

(3)?瀏覽器第一次訪問服務器時,服務器端會創建一個 session 對象,生成一個類似于 key,value 的鍵值對, 然后將 value 保存到服務器,將 key(cookie)返回到瀏覽器(客戶)端。
? ? ? 瀏覽器下次訪問時會攜帶 key(cookie),找到對應的 session(value)。

(4) sessions包地址:?github.com/gorilla/sessions

七、參數驗證

1.?結構體驗證

? ?用gin框架的數據驗證,可以不用解析數據,減少if else,會簡潔許多。

? ?比如,在定義結構體時,添加如下?binding:"required,gt=10",表示不能為空并且大于10

type Person struct {//不能為空并且大于10Age      int       `form:"age" binding:"required,gt=10"`
}
?2.?自定義驗證

? ? 可以自定義驗證函數,并注冊到 validator中。

? ? 包地址:gopkg.in/go-playground/validator.v9/translations

type Person struct {//1.在binding上使用自定義的 參數名稱 stringCheckNameName    string `form:"name" binding:"stringCheckName"`
}
//2.自定義的校驗方法
func checkStringValid(v *validator.Validate, ......) bool {if value, ok := field.Interface().(string); ok {return value != "" && !("5lmh" == value) //字段不能為空,并且不等于5lmh}return true
}
func main() {r := gin.Default()// 3、將我們自定義的校驗方法 和 參數名稱 注冊到 validator中if v, ok := binding.Validator.Engine().(*validator.Validate); ok {v.RegisterValidation("stringCheckName", checkStringValid)}
}
3.?多語言翻譯驗證

? ?如需要自定義返回信息的語言,比如部分用戶返回中文,部分返回英文。

? ?可以使用??validator.v9/translations

import (ut "github.com/go-playground/universal-translator"en_translations "gopkg.in/go-playground/validator.v9/translations/en"
)
func startPage(c *gin.Context) {locale := c.DefaultQuery("locale", "zh")  //1.獲得前端使用語言//2.獲得翻譯器en := en.New()zh := zh.New()Uni = ut.New(en, zh)trans, _ := Uni.GetTranslator(locale)     //3.注冊翻譯器Validate = validator.New()en_translations.RegisterDefaultTranslations(Validate, trans) //4.解析結構體,獲得翻譯過的內容user := User{}c.ShouldBind(&user)err := Validate.Struct(user)
}

八、其他

1. 日志

? 使用 io.MultiWriter ?和?gin.DefaultWriter

import ("io""os"
)
func main() {f, _ := os.Create("gin.log")gin.DefaultWriter = io.MultiWriter(f) //將日志寫入文件//gin.DefaultWriter = io.MultiWriter(f, os.Stdout) //將日志同時寫入文件和控制臺
}
2. Air 實時加載

? ??在開發調試的時候,變更代碼之后需要按下Ctrl+C停止程序并重新編譯再執行,不是很方便。

? ??Air能夠實時監聽項目的代碼文件,在代碼發生變更之后自動重新編譯并執行,提高開發效率。

3.?gin驗證碼

? ?為了防止接口被惡意頻繁調用,可以采用加驗證碼的方式。

? ?庫地址:github.com/dchest/captcha

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/19350.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/19350.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/19350.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【傳知代碼】BERT論文解讀及情感分類實戰-論文復現

文章目錄 概述原理介紹BERT模型架構任務1 Masked LM(MLM)任務2 Next Sentence Prediction (NSP)模型輸入下游任務微調GLUE數據集SQuAD v1.1 和 v2.0NER 情感分類實戰IMDB影評情感數據集數據集構建模型構建 核心代碼超參數設置訓練結果注意事項 小結 本文…

AIOps在線評測基準首階段建設完成,面向社區發布真實運維數據!

本文根據必示科技算法研究員、產品總監聶曉輝博士在2024 CCF國際AIOps挑戰賽線下宣講會上的演講整理成文。 2024年1月份OpenAIOps社區成立,隨著越來越多的社區成員加入,各項工作在有條不紊的推進中。在線評測基準系統(AIOps Live Benchmark&a…

積鼎CFDPro水文水動力模型,專為中小流域洪水“四預”研發的流體仿真技術

水動力模型與水文模型是水利工程與水文學研究中不可或缺的兩大工具。水動力模型著重于流體運動的動力學機制,通過一系列方程組捕捉水流的時空變化,而概念性水文模型則側重于流域尺度的水文循環過程,利用物理概念與經驗關系進行近似模擬。兩者…

Windows系統部署YOLOv5 v6.1版本的訓練與推理環境保姆級教程

文章目錄 一 概述二 依賴環境(prerequisites)2.1 硬件環境2.2 軟件環境 三 環境安裝3.1 創建并激活虛擬環境3.2 安裝Pytorch與torchvision3.3 校驗Pytorch安裝3.4 下載 YOLOv5 v6.1 源碼3.5 安裝 YOLOv5 依賴3.6 下載預訓練模型3.7 安裝其他依賴3.8 測試環境安裝3.9 測試訓練流…

jupyter notebook更改位置

1.找到jupyer的配置文件 一般在c盤用戶的.jupter文件夾下 2. 用記事本打開這個配置文件,定位到c.NotebookApp.notebook_dir /path_to_your_directory 替換你的位置 3.找到jupyer圖標的位置,打開屬性 添加要存放的位置在目標文件的末尾,重新…

python | spacy,一個神奇的 Python 庫!

本文來源公眾號“python”,僅用于學術分享,侵權刪,干貨滿滿。 原文鏈接:spacy,一個神奇的 Python 庫! 大家好,今天為大家分享一個神奇的 Python 庫 - spacy。 Github地址:https:/…

一個全面了解Xilinx FPGA IP核的窗口:《Xilinx系列FPGA芯片IP核詳解》(可下載)

隨著摩爾定律的逐漸放緩,傳統的芯片設計方法面臨著越來越多的挑戰。而FPGA以其并行處理能力和可編程性,為解決復雜問題提供了新的途徑。它允許設計者在同一個芯片上實現多種不同的功能模塊,極大地提高了資源的利用率和系統的綜合性能。 FPGA…

領域數據模型建設步驟

領域數據模型建設步驟 以某音樂app為例: 1.數據調研和業務調研,識別業務過程,實體,關鍵指標 業務過程:播放,收藏,下載,點擊,購買,支付 實體:音樂&#xff0c…

HCIA-ARP

ARP的由來 ARP這一種協議它會是在我們HCIA中第一個需要完全掌握的一個協議,不然對于數據通訊來說大家都會一直覺得很繞圈 協議棧,網線,網卡,它們組成了我們最小的數據通信的小脈絡注:可以了解ARP攻擊(冒充訪…

使用Java和MyBatis獲取表頭與數據

使用Java和MyBatis獲取表頭與數據 在數據處理與展示中,經常需要將數據庫查詢結果中的表頭(列名)與實際數據提取出來。本文將介紹如何通過Java的JDBC和MyBatis來實現這一需求。 1. 使用JDBC獲取表頭與數據 在JDBC中,可以使用Res…

文獻解讀-群體基因組第二期|《中國人群中PAX2新生突變的檢測及表型分析:一項單中心研究》

關鍵詞:應用遺傳流行病學;群體測序;群體基因組;基因組變異檢測; 文獻簡介 標題(英文):Detection of De Novo PAX2 Variants and Phenotypes in Chinese Population: A Single-Cente…

new CCDIKSolver( OOI.kira, iks ); // 創建逆運動學求解器

demo案例 new CCDIKSolver(OOI.kira, iks); 在使用某個特定的庫或框架來創建一個逆運動學(Inverse Kinematics, IK)求解器實例。逆運動學在機器人學、動畫和計算機圖形學等領域中非常重要,它用于根據期望的末端執行器(如機器人的…

Compose第四彈 Compose項目

目標: 1.可供學習的Compose項目 一、官方提供項目 谷歌官方提供的Compose項目: GitHub - android/compose-samples: Official Jetpack Compose samples. 項目及主要頁面展現 1.1 Reply項目 1.首頁底部TAB欄 2.側邊欄菜單:拖動滑出和收起…

建設現代智能工業-智能化、數字化、自動化節能減排

建設現代智能工業-智能化節能減排 遵循“一體化”能源管理(Integrated Energy Management)的設計宗旨,集成城市各領域(如工業.交通、建筑等)的能源生產和消費信息,面向城市政府、企業、公眾三類實體,提供“一體化”的綜合能源管理…

uniapp h5項目切換導航欄及動態渲染按鈕顏色

1.效果圖 2.html,動態渲染按鈕樣式---三元判斷 <!-- 切換欄 --><view class"statusList"><block v-for"(item,index) in list" :key"index"><view class"swiper-tab-list" :class"current item.id?activ…

CEEMDAN +組合預測模型(CNN-Transfromer + XGBoost)

注意&#xff1a;本模型繼續加入 組合預測模型全家桶 中&#xff0c;之前購買的同學請及時更新下載! 往期精彩內容&#xff1a; 時序預測&#xff1a;LSTM、ARIMA、Holt-Winters、SARIMA模型的分析與比較-CSDN博客 VMD CEEMDAN 二次分解&#xff0c;Transformer-BiGRU預測模…

靜態加速和動態加速是啥區別

以下是兩者之間的主要區別&#xff1a; 加速對象與內容&#xff1a; 靜態加速&#xff1a;主要針對網頁中的靜態資源&#xff0c;如HTML文件、CSS文件、JavaScript文件、圖片、Flash動畫等。這些資源的特點是更新頻率較低&#xff0c;適合通過緩存技術加速。 動態加速&#xf…

網絡學習(11) |深入解析客戶端緩存與服務器緩存:HTTP緩存控制頭字段及優化實踐

文章目錄 客戶端緩存與服務器緩存的區別客戶端緩存瀏覽器緩存應用程序緩存優點缺點 服務器緩存優點缺點 HTTP緩存控制頭字段Cache-ControlExpiresLast-ModifiedETag 緩存策略的優化與實踐經驗分享1. 使用合適的緩存頭字段2. 結合使用Last-Modified和ETag3. 利用CDN進行緩存4. 實…

【JAVA WEB實用與優化技巧】如何自己封裝一個自定義UI的Swagger組件,包含Swagger如何處理JWT無狀態鑒權自動TOKEN獲取

目錄 一、Swagger 簡介1. 什么是 Swagger&#xff1f;2. 如何使用 Swagger3. Springboot 中swagger的使用示例1. maven 引入安裝2. java配置 二、Swagger UI存在的缺點1.不夠方便直觀2.請求的參數沒有緩存3.不夠美觀4.如果是JWT 無狀態登錄&#xff0c;Swagger使用起來就沒有那…

STL-stack的使用及其模擬實現

在C標準庫中&#xff0c;stack是一種容器適配器&#xff0c;它以后進先出的方式組織數據&#xff0c;其刪除只能從容器的棧頂進行元素的插入與取出操作。 stack的使用 stack的構造函數 stack的成員函數 empty&#xff1a;判斷棧是否為空back&#xff1a;返回當前棧中元素的數量…