Java教程
成都創(chuàng)新互聯(lián)成立十載來,這條路我們正越走越好,積累了技術(shù)與客戶資源,形成了良好的口碑。為客戶提供成都網(wǎng)站建設(shè)、成都網(wǎng)站制作、網(wǎng)站策劃、網(wǎng)頁設(shè)計(jì)、國際域名空間、網(wǎng)絡(luò)營銷、VI設(shè)計(jì)、網(wǎng)站改版、漏洞修補(bǔ)等服務(wù)。網(wǎng)站是否美觀、功能強(qiáng)大、用戶體驗(yàn)好、性價(jià)比高、打開快等等,這些對(duì)于網(wǎng)站建設(shè)都非常重要,成都創(chuàng)新互聯(lián)通過對(duì)建站技術(shù)性的掌握、對(duì)創(chuàng)意設(shè)計(jì)的研究為客戶提供一站式互聯(lián)網(wǎng)解決方案,攜手廣大客戶,共同發(fā)展進(jìn)步。
Linux入門
更多
首頁
?
Go語言WEB框架(Gin)詳解
在 Go語言開發(fā)的 Web 框架中,有兩款著名 Web 框架分別是 Martini 和 Gin,兩款 Web 框架相比較的話,Gin 自己說它比 Martini 要強(qiáng)很多。
Gin 是 Go語言寫的一個(gè) web 框架,它具有運(yùn)行速度快,分組的路由器,良好的崩潰捕獲和錯(cuò)誤處理,非常好的支持中間件和 json。總之在 Go語言開發(fā)領(lǐng)域是一款值得好好研究的 Web 框架,開源網(wǎng)址:
首先下載安裝 gin 包:
go get -u github.com/gin-gonic/gin
一個(gè)簡(jiǎn)單的例子:
package main
import "github.com/gin-gonic/gin"
func main() {
//Default返回一個(gè)默認(rèn)的路由引擎
r := gin.Default()
r.GET("/ping", func(c *gin.Context) {
//輸出json結(jié)果給調(diào)用方
c.JSON(200, gin.H{
"message": "pong",
})
})
r.Run() // listen and serve on 0.0.0.0:8080
}
編譯運(yùn)行程序,打開瀏覽器,訪問頁面顯示:
{"message":"pong"}
gin 的功能不只是簡(jiǎn)單輸出 Json 數(shù)據(jù)。它是一個(gè)輕量級(jí)的 WEB 框架,支持 RestFull 風(fēng)格 API,支持 GET,POST,PUT,PATCH,DELETE,OPTIONS 等 http 方法,支持文件上傳,分組路由,Multipart/Urlencoded FORM,以及支持 JsonP,參數(shù)處理等等功能,這些都和 WEB 緊密相關(guān),通過提供這些功能,使開發(fā)人員更方便地處理 WEB 業(yè)務(wù)。
Gin 實(shí)際應(yīng)用
接下來使用 Gin 作為框架來搭建一個(gè)擁有靜態(tài)資源站點(diǎn),動(dòng)態(tài) WEB 站點(diǎn),以及 RESTFull API 接口站點(diǎn)(可專門作為手機(jī) APP 應(yīng)用提供服務(wù)使用)組成的,亦可根據(jù)情況分拆這套系統(tǒng),每種功能獨(dú)立出來單獨(dú)提供服務(wù)。
下面按照一套系統(tǒng)但采用分站點(diǎn)來說明,首先是整個(gè)系統(tǒng)的目錄結(jié)構(gòu),website 目錄下面 static 是資源類文件,為靜態(tài)資源站點(diǎn)專用;photo 目錄是 UGC 上傳圖片目錄,tpl 是動(dòng)態(tài)站點(diǎn)的模板。
當(dāng)然這個(gè)目錄結(jié)構(gòu)是一種約定,可以根據(jù)情況來修改。整個(gè)項(xiàng)目已經(jīng)開源,可以訪問來詳細(xì)了解:具體每個(gè)站點(diǎn)的功能怎么實(shí)現(xiàn)呢?請(qǐng)看下面有關(guān)每個(gè)功能的講述:
靜態(tài)資源站點(diǎn)
一般網(wǎng)站開發(fā)中,我們會(huì)考慮把 js,css,以及資源圖片放在一起,作為靜態(tài)站點(diǎn)部署在 CDN,提升響應(yīng)速度。采用 Gin 實(shí)現(xiàn)起來非常簡(jiǎn)單,當(dāng)然也可以使用 net/http 包輕松實(shí)現(xiàn),但使用 Gin 會(huì)更方便。
不管怎么樣,使用 Go 開發(fā),我們可以不用花太多時(shí)間在 WEB 服務(wù)環(huán)境搭建上,程序啟動(dòng)就直接可以提供 WEB 服務(wù)了。
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
router := gin.Default()
// 靜態(tài)資源加載,本例為css,js以及資源圖片
router.StaticFS("/public", http.Dir("D:/goproject/src/github.com/ffhelicopter/tmm/website/static"))
router.StaticFile("/favicon.ico", "./resources/favicon.ico")
// Listen and serve on 0.0.0.0:80
router.Run(":80")
}
首先需要是生成一個(gè) Engine,這是 gin 的核心,默認(rèn)帶有 Logger 和 Recovery 兩個(gè)中間件。
router := gin.Default()
StaticFile 是加載單個(gè)文件,而 StaticFS 是加載一個(gè)完整的目錄資源:
func (group *RouterGroup) StaticFile(relativePath, filepath string) IRoutes
func (group *RouterGroup) StaticFS(relativePath string, fs http.FileSystem) IRoutes
這些目錄下資源是可以隨時(shí)更新,而不用重新啟動(dòng)程序。現(xiàn)在編譯運(yùn)行程序,靜態(tài)站點(diǎn)就可以正常訪問了。
? 何為框架:
框架一直是敏捷開發(fā)中的利器,能讓開發(fā)者很快的上手并做出應(yīng)用,甚至有的時(shí)候,脫離了框架,一些開發(fā)者都不會(huì)寫程序了。成長總不會(huì)一蹴而就,從寫出程序獲取成就感,再到精通框架,快速構(gòu)造應(yīng)用,當(dāng)這些方面都得心應(yīng)手的時(shí)候,可以嘗試改造一些框架,或是自己創(chuàng)造一個(gè)。
Gin是一個(gè)golang的微框架,封裝比較優(yōu)雅,API友好,源碼注釋比較明確,已經(jīng)發(fā)布了1.0版本。具有快速靈活,容錯(cuò)方便等特點(diǎn)。其實(shí)對(duì)于golang而言,web框架的依賴要遠(yuǎn)比Python,Java之類的要小。自身的net/http足夠簡(jiǎn)單,性能也非常不錯(cuò)。框架更像是一些常用函數(shù)或者工具的集合。借助框架開發(fā),不僅可以省去很多常用的封裝帶來的時(shí)間,也有助于團(tuán)隊(duì)的編碼風(fēng)格和形成規(guī)范。
(1)首先需要安裝,安裝比較簡(jiǎn)單,使用go get即可
go get github.com/gin-gonic/gin
如果安裝失敗,直接去Github clone下來,放置到對(duì)應(yīng)的目錄即可。
(2)代碼中使用:
下面是一個(gè)使用Gin的簡(jiǎn)單例子:
package main
import (
"github.com/gin-gonic/gin"
)
func main() {
router := gin.Default()
router.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "pong",
})
})
router.Run(":8080") // listen and serve on 0.0.0.0:8080
}
簡(jiǎn)單幾行代碼,就能實(shí)現(xiàn)一個(gè)web服務(wù)。使用gin的Default方法創(chuàng)建一個(gè)路由handler。然后通過HTTP方法綁定路由規(guī)則和路由函數(shù)。不同于net/http庫的路由函數(shù),gin進(jìn)行了封裝,把request和response都封裝到gin.Context的上下文環(huán)境。最后是啟動(dòng)路由的Run方法監(jiān)聽端口。麻雀雖小,五臟俱全。當(dāng)然,除了GET方法,gin也支持POST,PUT,DELETE,OPTION等常用的restful方法。
Gin可以很方便的支持各種HTTP請(qǐng)求方法以及返回各種類型的數(shù)據(jù),詳情可以前往查看。
2.1 匹配參數(shù)
我們可以使用Gin框架快速的匹配參數(shù),如下代碼所示:
冒號(hào):加上一個(gè)參數(shù)名組成路由參數(shù)。可以使用c.Param的方法讀取其值。當(dāng)然這個(gè)值是字串string。諸如/user/rsj217,和/user/hello都可以匹配,而/user/和/user/rsj217/不會(huì)被匹配。
瀏覽器輸入以下測(cè)試:
返回結(jié)果為:
其中c.String是gin.Context下提供的方法,用來返回字符串。
其中c.Json是gin.Context下提供的方法,用來返回Json。
下面我們使用以下gin提供的Group函數(shù),方便的為不同的API進(jìn)行分類。
我們創(chuàng)建了一個(gè)gin的默認(rèn)路由,并為其分配了一個(gè)組 v1,監(jiān)聽hello請(qǐng)求并將其路由到視圖函數(shù)HelloPage,最后綁定到 0.0.0.0:8000
C.JSON是Gin實(shí)現(xiàn)的返回json數(shù)據(jù)的內(nèi)置方法,包含了2個(gè)參數(shù),狀態(tài)碼和返回的內(nèi)容。http.StatusOK代表返回狀態(tài)碼為200,正文為{"message": “welcome"}。
注:Gin還包含更多的返回方法如c.String, c.HTML, c.XML等,請(qǐng)自行了解。可以方便的返回HTML數(shù)據(jù)
我們?cè)谥暗慕Mv1路由下新定義一個(gè)路由:
下面我們?cè)L問
可以看到,通過c.Param(“key”)方法,Gin成功捕獲了url請(qǐng)求路徑中的參數(shù)。同理,gin也可以捕獲常規(guī)參數(shù),如下代碼所示:
在瀏覽器輸入以下代碼:
通過c.Query(“key”)可以成功接收到url參數(shù),c.DefaultQuery在參數(shù)不存在的情況下,會(huì)由其默認(rèn)值代替。
我們還可以為Gin定義一些默認(rèn)路由:
這時(shí)候,我們?cè)L問一個(gè)不存在的頁面:
返回如下所示:
下面我們測(cè)試在Gin里面使用Post
在測(cè)試端輸入:
附帶發(fā)送的數(shù)據(jù),測(cè)試即可。記住需要使用POST方法.
繼續(xù)修改,將PostHandler的函數(shù)修改如下
測(cè)試工具輸入:
發(fā)送的內(nèi)容輸入:
返回結(jié)果如下:
備注:此處需要指定Content-Type為application/x-www-form-urlencoded,否則識(shí)別不出來。
一定要選擇對(duì)應(yīng)的PUT或者DELETE方法。
Gin框架快速的創(chuàng)建路由
能夠方便的創(chuàng)建分組
支持url正則表達(dá)式
支持參數(shù)查找(c.Param c.Query c.PostForm)
請(qǐng)求方法精準(zhǔn)匹配
支持404處理
快速的返回給客戶端數(shù)據(jù),常用的c.String c.JSON c.Data
1.先安裝Go對(duì)應(yīng)的開源Swagger相關(guān)的庫
go get?github.com/swaggo/swag/cmd/swag
go get github.com/swaggo/gin-swagger
go get?github.com/swaggo/files
go get?github.com/alecthomas/template
2.驗(yàn)證是否安裝成功:swag -v
3.針對(duì)接口寫入注解
// @Summary 獲取多個(gè)標(biāo)簽
// @Tags 標(biāo)簽
// @Produce? json
// @Param name query string false "標(biāo)簽名稱" maxlength(100)
// @Param state query int false "狀態(tài)" Enums(0, 1) default(1)
// @Param page query int false "頁碼"
// @Param page_size query int false "每頁數(shù)量"
// @Success 200 {object} model.TagSwagger "成功"
// @Failure 400 {object} errcode.Error "請(qǐng)求錯(cuò)誤"
// @Failure 500 {object} errcode.Error "內(nèi)部錯(cuò)誤"
// @Router /api/v1/tags [get]
func (t Tag) List(c *gin.Context) {
}
// @Summary 新增標(biāo)簽
// @Tags 標(biāo)簽
// @Produce? json
// @Param name body string true "標(biāo)簽名稱" minlength(3) maxlength(100)
// @Param state body int false "狀態(tài)" Enums(0, 1) default(1)
// @Param created_by body string false "創(chuàng)建者" minlength(3) maxlength(100)
// @Success 200 {object} model.Tag "成功"
// @Failure 400 {object} errcode.Error "請(qǐng)求錯(cuò)誤"
// @Failure 500 {object} errcode.Error "內(nèi)部錯(cuò)誤"
// @Router /api/v1/tags [post]
func (t Tag) Create(c *gin.Context) {
}
// @Summary 更新標(biāo)簽
// @Tags 標(biāo)簽
// @Produce? json
// @Param id path int true "標(biāo)簽ID"
// @Param name body string false "標(biāo)簽名稱" minlength(3) maxlength(100)
// @Param state body int false "狀態(tài) (0為未刪除、1為已刪除)" Enums(0, 1) default(1)
// @Param modified_by body string true "修改者" minlength(3) maxlength(100)
// @Success 200 {array} model.Tag "成功"
// @Failure 400 {object} errcode.Error "請(qǐng)求錯(cuò)誤"
// @Failure 500 {object} errcode.Error "內(nèi)部錯(cuò)誤"
// @Router /api/v1/tags/{id} [put]
func (t Tag) Update(c *gin.Context) {
}
4.針對(duì)整個(gè)項(xiàng)目進(jìn)行注解,直接在main方法寫入如下注解
//@title 項(xiàng)目名稱
//@version 1.0
//@description 這里是描述
func main() {
5.生成執(zhí)行 swag init
這時(shí)會(huì)在我項(xiàng)目的docs文件夾下面生成docs.go、swagger.json、swagger.yaml三個(gè)文件
6.要在routers中進(jìn)行默認(rèn)初始化和注冊(cè)對(duì)應(yīng)的路由:
r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
同時(shí)要引用 _"blog-service/docs" ,不然會(huì)報(bào)錯(cuò)
7.查看接口文檔 :
8.ok,完成
是的
M代表一個(gè)內(nèi)核線程,也可以稱為一個(gè)工作線程。goroutine就是跑在M之上的。(兩個(gè)M如果運(yùn)行在一個(gè)CPU上就是并發(fā),如果運(yùn)行在不同CPU就是并行。)
P 代表著處理器,或是程序執(zhí)行上下文,將等待執(zhí)行的G與M對(duì)接。Go的運(yùn)行時(shí)系統(tǒng)會(huì)適時(shí)地讓P與不同的M建立或斷開關(guān)聯(lián),以使P中的那些可運(yùn)行的G能夠及時(shí)獲得運(yùn)行時(shí)機(jī);
G代表協(xié)程(是一個(gè)輕量級(jí)的執(zhí)行線程),可以有多個(gè);
(go采用了基于消息并發(fā)模型的方式。它將基于CSP模型的并發(fā)編程內(nèi)置到了語言中,通過一個(gè)go關(guān)鍵字就可以輕易地啟動(dòng)一個(gè)Goroutine,而且在Goroutine之間是共享內(nèi)存的。)
ORM-Object-Relationl Mapping,即對(duì)象關(guān)系映射,這里的Relationl指的是關(guān)系型數(shù)據(jù)庫
它的作用是在關(guān)系型數(shù)據(jù)庫和對(duì)象之間作一個(gè)映射,這樣,我們?cè)诰唧w的操作數(shù)據(jù)庫的時(shí)候,就不需要再去和復(fù)雜的SQL語句打交道,只要像平時(shí)操作對(duì)象一樣操作它就可以了
GORM就是go語言實(shí)現(xiàn)的一個(gè)ORM庫
特點(diǎn):
增加(Create)
檢索(Retrieve)
更新(Update)
刪除(Delete)
如果模型中有 DeletedAt 字段,它將自動(dòng)擁有軟刪除的能力!當(dāng)執(zhí)行刪除操作時(shí),數(shù)據(jù)并不會(huì)永久的從數(shù)據(jù)庫中刪除,而是將 DeletedAt 的值更新為當(dāng)前時(shí)間。
具體的使用可查看gorm 官方文檔
在項(xiàng)目中我們定義一個(gè)全局的GVA_DB,方便使用時(shí)調(diào)用
后續(xù)我們?cè)谛枰樵償?shù)據(jù)庫時(shí)便可直接通過global.GVA_DB使用
比如創(chuàng)建商品信息:
我們先通過查詢分類是否存在,然后再創(chuàng)建商品
通過gorm的鏈?zhǔn)讲僮骺梢院芊奖愕倪M(jìn)行crud操作
分頁查詢是項(xiàng)目中經(jīng)常使用到的功能,當(dāng)指定條件查詢的數(shù)據(jù)量過大時(shí),如果我們將數(shù)據(jù)一次性返回,會(huì)對(duì)數(shù)據(jù)庫造成較大的負(fù)荷,同時(shí)降低接口的性能,通常我們會(huì)使用分頁查詢的方式讓數(shù)據(jù)進(jìn)行分段展示,從而保障接口的性能。在gorm中我們實(shí)用Offset,和Count來實(shí)現(xiàn)分頁
我們通過前端的傳遞過來的分頁數(shù)據(jù)進(jìn)行查詢
該商城作為gin的學(xué)習(xí)項(xiàng)目,沒有很復(fù)雜的邏輯,所有業(yè)務(wù)邏輯均通過Mysql實(shí)現(xiàn)。包括后面將要介紹的登錄態(tài),也是如此。
所有代碼已上傳github,有興趣的可以訪問,如果有更好的建議也歡迎提交issure,pr
當(dāng)客戶端在 發(fā)出POST請(qǐng)求時(shí)/albums,您希望將請(qǐng)求正文中描述的專輯添加到現(xiàn)有專輯數(shù)據(jù)中。
為此,您將編寫以下內(nèi)容:
1、編寫代碼
a.添加代碼以將專輯數(shù)據(jù)添加到專輯列表。
在此代碼中:
1)用于Context.BindJSON 將請(qǐng)求正文綁定到newAlbum。
2) album將從 JSON 初始化的結(jié)構(gòu)附加到albums 切片。
3)向響應(yīng)添加201狀態(tài)代碼,以及表示您添加的專輯的 JSON。
b.更改您的main函數(shù),使其包含該router.POST函數(shù),如下所示。
在此代碼中:
1)將路徑中的POST方法與 /albumspostAlbums函數(shù)相關(guān)聯(lián)。
使用 Gin,您可以將處理程序與 HTTP 方法和路徑組合相關(guān)聯(lián)。這樣,您可以根據(jù)客戶端使用的方法將發(fā)送到單個(gè)路徑的請(qǐng)求單獨(dú)路由。
a.如果服務(wù)器從上一節(jié)開始仍在運(yùn)行,請(qǐng)停止它。
b.從包含 main.go 的目錄中的命令行,運(yùn)行代碼。
c.從不同的命令行窗口,用于curl向正在運(yùn)行的 Web 服務(wù)發(fā)出請(qǐng)求。
該命令應(yīng)顯示添加專輯的標(biāo)題和 JSON。
d.與上一節(jié)一樣,使用curl檢索完整的專輯列表,您可以使用它來確認(rèn)添加了新專輯。
該命令應(yīng)顯示專輯列表。
當(dāng)客戶端向 發(fā)出請(qǐng)求時(shí)GET /albums/[id],您希望返回 ID 與id路徑參數(shù)匹配的專輯。
為此,您將:
a.在您在上一節(jié)中添加的函數(shù)下方postAlbums,粘貼以下代碼以檢索特定專輯。
此getAlbumByID函數(shù)將提取請(qǐng)求路徑中的 ID,然后找到匹配的專輯。
在此代碼中:
(1)Context.Param用于從 URL 中檢索id路徑參數(shù)。當(dāng)您將此處理程序映射到路徑時(shí),您將在路徑中包含參數(shù)的占位符。
(2)循環(huán)album切片中的結(jié)構(gòu),尋找其ID 字段值與id參數(shù)值匹配的結(jié)構(gòu)。如果找到,則將該album結(jié)構(gòu)序列化為 JSON,并將其作為帶有200 OK HTTP 代碼的響應(yīng)返回。
如上所述,實(shí)際使用中的服務(wù)可能會(huì)使用數(shù)據(jù)庫查詢來執(zhí)行此查找。
(3)如果找不到專輯,則返回 HTTP 404錯(cuò)誤。
b.最后,更改您的main,使其包含對(duì)router.GET的新調(diào)用,路徑現(xiàn)在為/albums/:id ,如以下示例所示。
在此代碼中:
(1)將/albums/:id路徑與getAlbumByID功能相關(guān)聯(lián)。在 Gin 中,路徑中項(xiàng)目前面的冒號(hào)表示該項(xiàng)目是路徑參數(shù)。
a.如果服務(wù)器從上一節(jié)開始仍在運(yùn)行,請(qǐng)停止它。
b.在包含 main.go 的目錄中的命令行中,運(yùn)行代碼以啟動(dòng)服務(wù)器。
c.從不同的命令行窗口,用于curl向正在運(yùn)行的 Web 服務(wù)發(fā)出請(qǐng)求。
該命令應(yīng)顯示您使用其 ID 的專輯的 JSON。如果找不到專輯,您將收到帶有錯(cuò)誤消息的 JSON。
恭喜!您剛剛使用 Go 和 Gin 編寫了一個(gè)簡(jiǎn)單的 RESTful Web 服務(wù)。
本節(jié)包含您使用本教程構(gòu)建的應(yīng)用程序的代碼。
新聞名稱:go語言gin go語言gin框架
URL地址:http://chinadenli.net/article42/doddsec.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供云服務(wù)器、網(wǎng)站營銷、面包屑導(dǎo)航、做網(wǎng)站、網(wǎng)站內(nèi)鏈、營銷型網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)