課上講義c04l01 gin框架說明快速掌握Gin和Web編程_第1頁
課上講義c04l01 gin框架說明快速掌握Gin和Web編程_第2頁
課上講義c04l01 gin框架說明快速掌握Gin和Web編程_第3頁
課上講義c04l01 gin框架說明快速掌握Gin和Web編程_第4頁
課上講義c04l01 gin框架說明快速掌握Gin和Web編程_第5頁
已閱讀5頁,還剩27頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

GoLand2019.2GoModulesweb路由(uri解析/restful設(shè)計(jì)validator驗(yàn)證(業(yè)務(wù)代碼的驗(yàn)證和檢驗(yàn))db/orm/sqlbuilder結(jié)構(gòu)體映射,序列化等)GinisaHTTPwebframeworkwritteninGo(Golang).ItfeaturesaMartini-likeAPIwithmuchbetterperformance--upto40timesfaster.Ifyouneedsmashingperformance,getyourselfsomeGin.httprouter的性能提高了40倍。ginGo Go

,G項(xiàng)目的

|oGo Go

文件。gomod /gin-gonic/gingogo

gogoget-o import( )funcmain()router:=gin.Default()} packagepackagemainimport( )funcmain()router:=添加Getrouter.GET("/",func(context{context.String(http.StatusOK, o} packagepackageimport )funcSetupRouter()*gin.Engine{router:=gin.Default()添加Getrouter.GET("/",func(context{context.String(http.StatusOK," returnpackagepackageimport )funcmain()router:=_=} packagepackageimport )funcTestIndexGetRouter(t*testing.T){router:=initRouter.SetupRouter()w:=reqreq,_:=http.NewRequest(http.MethodGet,"/",nil)router.ServeHTTP(w,req)assert.Equal(t,http.StatusOK,w.Code)assert.Equal(t," ogin",w.Body.String())}|o||-|o||-|||-|GiGo/Ginhttp服務(wù)?很簡(jiǎn)單,也很方便,Gin服務(wù)默認(rèn)服務(wù) funcfuncmain()router:=gin.Default()http.ListenAndServe(":8080",router)}funcfuncmain()router:=s:= 10*time.Second, 10*time.Second,MaxHeaderBytes:1<<20,}}基本路由gin框架中采用的路由庫是httprouter創(chuàng)建帶有默認(rèn)中間件的路由router:=//r:=router.GET("/someGet",getting)router.POST("/somePost",posting)router.PUT("/somePut",putting)router.DELETE("/someDelete",deleting)router.PATCH("/somePatch",patching)router.HEAD("/someHead",head) routerrouter.Any("/some",到路由的請(qǐng)求都返回views/404.html頁面。rr.NoRoute(func(c{c.HTML(http.StatusNotFound,"views/404.html",的路由來自APIapi參數(shù)通過Context的Paramrouterrouter.GET("/user/:name",func(c{name:=c.Param("name")c.String(http.StatusOK,name)諸如/user/ls,和/user/o都可以匹配,而/user和/user/ls/不會(huì)被匹配。routerrouter.GET("/user/:name/*action",func(c*gin{name:=c.Param("name")action:=c.Param("action")message:=name+"is"+actinc.String(http.StatusOKmessage)除了,gin還提供了**URL數(shù)無非兩種,查詢字符串querystring和報(bào)文體body參數(shù)。所謂querystring,即路由用,用以后連接的key1=value2&key2=value2的形式的參數(shù)。當(dāng)然這個(gè)key-value是經(jīng)過urlencode編碼。URLDefaultQueryQuery優(yōu)雅的方案,使用c.DefaultQuery方法參數(shù),其中當(dāng)參數(shù)不存在的時(shí)候,提供一個(gè)默認(rèn)值。使用funcfuncmain()router:= e",func(c*gin.Context)name:c.DefaultQuery("name""Guest"http:////nicknamec.Query("nickname")c.String(http.StatusOK, o%s",}http的報(bào)文體傳輸數(shù)據(jù)就比querystring稍微復(fù)雜一點(diǎn),常見的格式就有四種。例如application/json,application/x-www-form-urlencoded,application/xml和multipart/form-data。后面一個(gè)主要用于上傳。json格式的很好理解,urlencode其實(shí)也不難,無非就是把querystring的內(nèi)容,放到了body體里,同樣也需要urlencode。默認(rèn)情況下,c.PostFROM解析的是x-www-form-urlencoded或from-data的參數(shù)。funcfuncmain()router:=router.POST("/form",func(cgin.Context)type1:c.DefaultPostFormtype"alert"http://可設(shè)置默認(rèn)值username:=c.PostForm("usernme")password:=c.PotForm("pas//hobbys:=c//hobbys:=hobbys:=c.String(http.StatusOK,fmt.Sprintf("typeis%s,usernameis%s,passwordis%s,hobbyis%v",type1,username,password,hobbys))}<!DOCTYPE<!DOCTYPE<html<metacharset="UTF-<formaction=" "method="post"用戶名:<inputtype="text"&&碼:<inputtype="password"&&<inputtype="checkbox"value="girl"name="hobby"><inputtype="checkbox"value="game"name="hobby"><inputtype="checkbox"value="money"name="hobby"><inputtype="submit"value="登錄multiprt/fom-dat轉(zhuǎn)用于文件上傳。gin文件上傳也很方便,和原生的net/http方法類似,不同在于gin把原生的requet封裝到c.Request中了。funcfuncmain()router:=gin.Defau//Setalowermemorylimitformultipartforms(defaultis32//router.MaxMultipartMemory=8<<20//8MiBrouter.POST("/upload",func(c*gin.Context){//singlefile,_:=c.FormFile("file")//Uploadthefiletospecificc.SaveUploadedFile(file,out,erros.Create(filename)deferout.Close()_,err=io.Copy(out,cc.String(http.StatusOK,fmt.Sprintf("'%s'uploaded!",}使用的操作,把文件數(shù)據(jù)到硬盤上。<!DOCTYPE<!DOCTYPE<html<metacharset="UTF-<formaction="<inputtype="file"<inputtype="submit"value="提交"lsls:~tedu$curl-X s/pro/momo.mp4"-H"Content-Type:multipart/form-packagepackageimport )funcmain()routerrouter:=//Setalowermemorylimitformultipartforms(defaultis32MiB)router.MaxMultipartMemory=8<<20//8MiB//router.Static("/","./public")router.POST("/upload",func(c*gin.Context){//Multipartform,err:=c.MultipartForm()iferr!=nil{c.String(http.StatusBadRequest,fmt.Sprintf("getformerr:%s",}files:=for_,file:=rangefilesiferr:=c.SaveUploadedFile(file,file.Filename);err!={c.String(http.StatusBadRequest,fmt.Sprintf("uploadfile%s",}}c.String(http.StatusOK,fmt.Sprintf("Uplodedsuccessfully%dfiles",}<!DOCTYPE<!DOCTYPE<html<metacharset="UTF-<form"Files:<inputtype="file"name="files"<inputtype="submit"value="提交routergroup是為了方便一部分相同的URL的管理,新建一個(gè)go文件packagemainimport( )funcmain()router:=//Simplegroup:v1:={v1.GET("/login",loginEndpoint)v1.GET("/submit",submitEndpoint)v1.POST("/read",readEndpoint)}//Simplegroup:v2:={v2.POST("/login",lognEndpoint)v2.POST("/submit",submitEndpoint)v2.POST("/read",readEndpoit)}}funcloginEndpoint(c*gin.Context)name:=c.DefaultQuery("name","Guest")//可設(shè)置默認(rèn)值c.String(http.StatusOK,fmt.Sprintf(" o%s\n",name))}funcsubmitEndpoint(c*gin.Context)name:=c.DefaultQuery("name","Guest")//可設(shè)置默認(rèn)值c.String(http.StatusOK,fmt.Sprintf(" o%s\n",name))}funcreadEndpoint(c*gin.Context)name:=c.DefaultQuery("name","Guest")//可設(shè)置默認(rèn)值c.String(http.StatusOK,fmt.Sprintf(" o%s\n",name))}lsls:~edu$shopGroupshopGroup:={shopGroup.GET("/index",func(c*gin.Context){...})shopGroup.GET("/cart",func(c*gin.Context){...})shopGroup.POST("/checkout",func(c*gin.Context){...})xx:=shopGroup.Group("xx")//r.Group(xx)xx.GET("/oo",func(c*gin.Context){...})}來說,,就是根據(jù)Body數(shù)據(jù)類型,將數(shù)據(jù)賦值到指定的結(jié)構(gòu)體變量中(類似于序列化和反序列化)。方法:BindBindJSONBindXMLBindQuery用c.AbortWithError(400).SetType(ErrorTypeBind)即可。將響應(yīng)狀態(tài)代碼設(shè)置為400,Content-Typeheader設(shè)置為text/ 設(shè)置響應(yīng)代碼,將會(huì)受到警告:[GIN-debug][WARNING]Headerswerealreadywritten.Wantedtooverridestatuscode400with422將導(dǎo)致已經(jīng)編寫了警方,,注意,使用綁定方法時(shí),GinContent-Type來自動(dòng)判斷需要解析的類型。如果你明確JSON

packagepackageimport )typeLoginstructstring`form:"username"json:"uer"uri:"user"Passwordstring`form:"password"jon:"password"uri:"password"xml:"password"binding:"required"`}funcmain()router:=//1.binding//ExampleforbndinJSON({"user":"ls","password":"123456"})router.POST("/loginJSON"func(c*gin.Context){varjsoniferr:=c.ShouldBindJSON(&json);err!=nil{c.JSON(http.StatusBadRequest,gin.H{"error":err.Error()})}ifjson.User!="ls"||json.Password!={c.JSON(http.StatusUnauthorized,gin.H{"status":"unauthorized"})return}c.JSON(http.StatusOK,gin.H{"status":"youarelogged}前面我們使用c.String返回響應(yīng),顧名思義則返回string類型。content-type是in或者text。調(diào)用lsls:~edu$curl-v-X-Htype:application/json'-dlsls:~edu$curl-v-Xtype:application/json'-d-H3.Form//ExampleforbindingaHTMLform(user=ls&password=123456)router.POST("/loginForm"func(cgin.Context){varform//方法一:對(duì)于FORM數(shù)據(jù)直接使用Bnd函數(shù)默認(rèn)使用使用form格式解析,ifc.Bind(&form)==nil//根據(jù)請(qǐng)求頭中 onenttype自動(dòng)推斷.iferr:=c.Bind(&form);err!=nil{c.JSON(http.StatusBadRequest,gin.H{"error":err.Error()})}ifform.User!="ls"||form.Password!="123456"{c.JSON(http.StatusUnauthorized,gin.H{"status":"unauthorized"})}c.JSON(http.StatusOK,gin.H{"status":"youareloggedrouterrouter.POST("/login",func(c{varform://你可以顯 //c.BindWith(&form,或者使用自動(dòng)推斷ifc.BindWith(&form,binding.Form)==nilifform.User=="user"&&form.Password=={c.JSON(200,gin.H{"status":"youarelogged }elsec.JSON(401,gin.H{"status":}}URI////router.GET("/:user/:password",func(c{varloginiferr:=c.ShouldBindUri(&login);err!={c.JSON(400,gin.H{"msg":err})}c.JSON(200,gin.H{"username":login.User,"password":lsls:~edu$curl-既然請(qǐng)求可以使用不同的content-type,響應(yīng)也如此。通常響應(yīng)會(huì)有html,text,in,json和等。JSON/XML/YAMLpackagepackageimport(")funcmain()r:=//gin.Hisashortcutformap[string]interface{}r.GET("/someJSON",func(c*gin.Context){c.JSON(http.StatusOK,gin.H{"message":"hey","status":r.GET("/moreJSON",func(c*gin.Context)//Youalsocanuseastructvarmsgstruct{ string`json:"user"`MessagestringNumber}msg.Name="ls"msg.Message="hey"msg.Number=123注意msg.Name變成了"user"http://以下方式都會(huì)輸出: {"user":"ls",Message":"hey","Number":123}c.JSON(http.StatusOK,msg)r.GET("/someXML",func(c*gin.Conext)c.XML(http.StatusOK,gin.H{"user":"ls","message":"hey","status":r.GET("/someYAML,fu(c*gin.Context)c.YAML(http.StatusOKgin.H{"message":"hey","status":r.GET("/someProtoBuf",func(c{reps:=[]int64{int64(1),int64(2)}label:="test"http://Thespecificdefinitionofprotobufiswritteninthetestdata/protoexamplefile.data&protoexample.Test{Label:Reps:}//Notethat esbinarydatainthe//Willoutputprotoexample.Testprotobufserializeddatac.ProtoBuf(http.StatusOK,data)//Listenandserveon}運(yùn)行項(xiàng)目,打開瀏覽?輸入:, 或者LoadHTMLFiles()方法來加載模板文件funcfuncmain()router:= router.GET("/index",func(c*gin.Context)c.HTML(http.StatusOK"index.tmpl"gin.H{"title":"Main}創(chuàng)建一 :temtes,然后在 tem{{.title router.GET("/posts/index",func(c{c.HTML(http.StatusOK,"posts/index.tmpl","title":c.HTML(http.StatusOK,"users/index.tmpl",gin.H{"title":"Users",importimport funcmain()router:=html:=tem te.ParseFiles("file1","file2")) }funcfuncmain()router:=gin.Defaul() teFuncMap{"safe":func(strstring) te.HTML{return router.GET("/index",func(c*gin.Context){c.HTML(http.StatusOK,"index.tmpl","<ahref='https:}在<!<!DOCTYPE<html <div>{{.|safeGin框架默認(rèn)都是使用單模板,如果需要使用blocktem te功能,可以通過" te"庫實(shí)現(xiàn),具體示例如下: 下的temtes文件夾下有以下模板文件,其中home.tmpl和index.tmpl繼承了base.tmpl: !"" !""home.tmpl $""index.tmpl!"" $""$""然后我們定義一個(gè) funcfunc tesDirstring) {r:= teNewRenderlayouts,err:=filepathGlob(temiferr!=nil{}includes,err:=filepath.Glob(temiferr!=nil{}tesDir+tesDir+//為layouts/和 生成 tesfor_,include:=rangeincludes{layoutCopy:=make([]string,len(layouts))copy(layoutCopy,layouts)files:=append(layoutCopy,include)r.AddFromFiles(filepath.Base(include),files...)}return}funcfuncindexFunc(c*gin.Context){c.HTML(http.StatusOK,"index.tmpl",nil)}funchomeFunc(c*gin.Context){c.HTML(http.StatusOK,"home.tmpl",nil)}funcr:=r.HTMLRender=loadTem r.GET("/index",indexFunc)r.GET("/home",homeFunc)}packagepackageimport )funcmain()router:=//顯示當(dāng)前文件夾下的所有文件/或者指定文件router.StaticFS("/showDir",http.Dir("."))router.StaticFS("/files"http.Dir("/bin")) //router.Static("/files",router.StaticFile("/image",}packagepackageimport )funcmain()r:=r.GET("/redirect",func(c*gin.Context)c.Redirect(http.StatusMovedPermanently"ht}打開瀏覽?輸入:rr.GET("/test",func(c*gin.Context)//指定重定向的URLc.Request.URL.Path"/test2"r.GET("/test2",func(c{c.JSON(http.StatusOK, o":goroutine機(jī)制可以方便地實(shí)現(xiàn)異步處理。當(dāng)在中間件或處理程序中啟動(dòng)新的Goroutines時(shí),你不應(yīng)該packagepackageimport)funcmain()r:=//1.r.GET("/long_async",func(c*gin.Context)goroutine:=gofunc()time.Sleep(5*log.Println("Done!inpath"http://2.r.GET("/long_sync",func(c{time.Sleep(5*log.Println("Done!in +//Listenandserveon00.} Gin 是的,它的構(gòu)造如下typetypeContextstruct{writermemresponseWriter handlersHandlersChain Accepted} 我們通過源碼可以知道就是[]HandlerFuc.而它的簽名正是typetypeHandlerFunc

funcfuncMiddleWare(){returnfunc(c*gin.Context){t:=time.Now()fmt.Println("beforec.Set("request"," //status:=c.Writer.Status()fmt.Println("aftermiddleware,",status)t2:=time.Since(t)fmt.Println("time:",}}}routerrouter:={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, }使用router/middlerware即可requestlsls:~edu$Next() 的分水嶺,就是這個(gè)c.Next(),否則沒有辦法傳遞中間件。服務(wù)端使用Use方法導(dǎo)入middleware,當(dāng)請(qǐng)求/middleware來到的時(shí)候,會(huì)執(zhí)行MiddleWare()c.Next()即的匿名函數(shù),然后回到本函數(shù)繼續(xù)執(zhí)行,所以本例的Print的輸出順序是:fmtfmt.Println("beforemiddleware")fmt.Println("aftermiddleware,",status)fmt.Println("time:",fmt.Println("aftermiddleware,",statusfmt.Println("request:",request執(zhí)行的順序就調(diào)換了。所以一切都取決于c.Next()執(zhí)行的位置。c.Next()的代碼如下:////Nextshouldbeusedonlyinside//Itexecutesthependinghandlersinthechaininsidethecalling//Seeexamplein f

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論