新聞中心
對(duì)象注冊(cè)注冊(cè)一個(gè)實(shí)例化的對(duì)象,以后每一個(gè)請(qǐng)求都交給該對(duì)象(同一對(duì)象)處理,該對(duì)象常駐內(nèi)存不釋放。

成都創(chuàng)新互聯(lián)長(zhǎng)期為上千家客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊(duì)從業(yè)經(jīng)驗(yàn)10年,關(guān)注不同地域、不同群體,并針對(duì)不同對(duì)象提供差異化的產(chǎn)品和服務(wù);打造開(kāi)放共贏平臺(tái),與合作伙伴共同營(yíng)造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為常山企業(yè)提供專業(yè)的成都做網(wǎng)站、成都網(wǎng)站設(shè)計(jì),常山網(wǎng)站改版等技術(shù)服務(wù)。擁有10多年豐富建站經(jīng)驗(yàn)和眾多成功案例,為您定制開(kāi)發(fā)。
相關(guān)方法:
func (s *Server) BindObject(pattern string, object interface{}, methods ...string) error
func (s *Server) BindObjectMethod(pattern string, object interface{}, method string) error
func (s *Server) BindObjectRest(pattern string, object interface{}) error
對(duì)象注冊(cè)
我們可以通過(guò)?BindObject?方法完成對(duì)象的注冊(cè)。
package main
import (
"github.com/GOgf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
)
type Controller struct{}
func (c *Controller) Index(r *ghttp.Request) {
r.Response.Write("index")
}
func (c *Controller) Show(r *ghttp.Request) {
r.Response.Write("show")
}
func main() {
s := g.Server()
c := new(Controller)
s.BindObject("/object", c)
s.SetPort(8199)
s.Run()
}可以看到,對(duì)象在進(jìn)行路由注冊(cè)時(shí)便生成了一個(gè)對(duì)象(對(duì)象在?Server?啟動(dòng)時(shí)便生成),此后不管多少請(qǐng)求進(jìn)入,?Server?都是將請(qǐng)求轉(zhuǎn)交給該對(duì)象對(duì)應(yīng)的方法進(jìn)行處理。需要注意的是,公開(kāi)方法的定義,必須為以下形式:
func(r *ghttp.Request)否則無(wú)法完成注冊(cè),調(diào)用注冊(cè)方法時(shí)會(huì)有錯(cuò)誤提示,例如:
panic: interface conversion: interface {} is xxx, not func(*ghttp.Request)該示例執(zhí)行后,終端輸出的路由表如下:
SERVER | DOMAIN | ADDRESS | METHOD | ROUTE | HANDLER | MIDDLEWARE
|---------|---------|---------|--------|---------------|--------------------------|------------|
default | default | :8199 | ALL | /object | main.(*Controller).Index |
|---------|---------|---------|--------|---------------|--------------------------|------------|
default | default | :8199 | ALL | /object/index | main.(*Controller).Index |
|---------|---------|---------|--------|---------------|--------------------------|------------|
default | default | :8199 | ALL | /object/show | main.(*Controller).Show |
|---------|---------|---------|--------|---------------|--------------------------|------------|隨后可以通過(guò) http://127.0.0.1:8199/object/show 查看效果。
控制器中的?Index?方法是一個(gè)特殊的方法,例如,當(dāng)注冊(cè)的路由規(guī)則為?/user?時(shí),?HTTP?請(qǐng)求到?/user?時(shí),將會(huì)自動(dòng)映射到控制器的?Index?方法。也就是說(shuō),訪問(wèn)地址?/user?和?/user/index?將會(huì)達(dá)到相同的執(zhí)行效果。
路由內(nèi)置變量
當(dāng)使用?BindObject?方法進(jìn)行對(duì)象注冊(cè)時(shí),在路由規(guī)則中可以使用兩個(gè)內(nèi)置的變量:?{.struct}?和?{.method}?,前者表示當(dāng)前對(duì)象名稱,后者表示當(dāng)前注冊(cè)的方法名。我們來(lái)看一個(gè)例子:
package main
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
)
type Order struct{}
func (o *Order) List(r *ghttp.Request) {
r.Response.Write("list")
}
func main() {
s := g.Server()
o := new(Order)
s.BindObject("/{.struct}-{.method}", o)
s.SetPort(8199)
s.Run()
}package main
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
)
type Order struct{}
func (o *Order) List(r *ghttp.Request) {
r.Response.Write("list")
}
func main() {
s := g.Server()
o := new(Order)
s.BindObject("/{.struct}-{.method}", o)
s.SetPort(8199)
s.Run()
}執(zhí)行后,終端輸出的路由表如下:
SERVER | DOMAIN | ADDRESS | METHOD | ROUTE | HANDLER | MIDDLEWARE
|---------|---------|---------|--------|-------------|--------------------|------------|
default | default | :8199 | ALL | /order-list | main.(*Order).List |
|---------|---------|---------|--------|-------------|--------------------|------------|我們嘗試著訪問(wèn) http://127.0.0.1:8199/order-list ,可以看到頁(yè)面輸出?list?。如果路由規(guī)則中不使用內(nèi)置變量,那么默認(rèn)的情況下,方法將會(huì)被追加到指定的路由規(guī)則末尾。
命名風(fēng)格規(guī)則
通過(guò)對(duì)象進(jìn)行路由注冊(cè)時(shí),可以根據(jù)對(duì)象及方法名稱自動(dòng)生成路由規(guī)則,默認(rèn)的路由規(guī)則為:當(dāng)方法名稱帶有多個(gè)單詞(按照字符大寫(xiě)區(qū)分單詞)時(shí),路由控制器默認(rèn)會(huì)自動(dòng)使用英文連接符號(hào)-進(jìn)行拼接,因此訪問(wèn)的時(shí)候方法名稱需要帶-號(hào)。
例如,方法名為?UserName?時(shí),生成的路由為?user-name?;方法名為?ShowListItems?時(shí),生成的路由為?show-list-items?;以此類推。
此外,我們可以通過(guò)?.Server.SetNameToUriType?方法來(lái)設(shè)置對(duì)象方法名稱的路由生成方式。支持的方式目前有4種,對(duì)應(yīng)4個(gè)常量定義:
UriTypeDefault = 0 // (默認(rèn))全部轉(zhuǎn)為小寫(xiě),單詞以'-'連接符號(hào)連接
UriTypeFullName = 1 // 不處理名稱,以原有名稱構(gòu)建成URI
UriTypeAllLower = 2 // 僅轉(zhuǎn)為小寫(xiě),單詞間不使用連接符號(hào)
UriTypeCamel = 3 // 采用駝峰命名方式注意:需要在通過(guò)對(duì)象進(jìn)行路由注冊(cè)前進(jìn)行該參數(shù)的設(shè)置,在路由注冊(cè)后設(shè)置將不會(huì)生效,那么將使用默認(rèn)規(guī)則。
我們來(lái)看一個(gè)示例:
package main
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
)
type User struct{}
func (u *User) ShowList(r *ghttp.Request) {
r.Response.Write("list")
}
func main() {
u := new(User)
s1 := g.Server("UriTypeDefault")
s2 := g.Server("UriTypeFullName")
s3 := g.Server("UriTypeAllLower")
s4 := g.Server("UriTypeCamel")
s1.SetNameToUriType(ghttp.UriTypeDefault)
s2.SetNameToUriType(ghttp.UriTypeFullName)
s3.SetNameToUriType(ghttp.UriTypeAllLower)
s4.SetNameToUriType(ghttp.UriTypeCamel)
s1.BindObject("/{.struct}/{.method}", u)
s2.BindObject("/{.struct}/{.method}", u)
s3.BindObject("/{.struct}/{.method}", u)
s4.BindObject("/{.struct}/{.method}", u)
s1.SetPort(8100)
s2.SetPort(8200)
s3.SetPort(8300)
s4.SetPort(8400)
s1.Start()
s2.Start()
s3.Start()
s4.Start()
g.Wait()
}為了對(duì)比演示效果,這個(gè)示例采用了多?Server?運(yùn)行方式,將不同的名稱轉(zhuǎn)換方式使用了不同的?Server?來(lái)配置運(yùn)行,因此我們可以方便地在同一個(gè)程序中,訪問(wèn)不同的?Server?(通過(guò)不同的端口綁定)看到不同的結(jié)果。
執(zhí)行后,終端輸出的路由表如下:
SERVER | DOMAIN | ADDRESS | METHOD | ROUTE | HANDLER | MIDDLEWARE
-----------------|---------|---------|--------|-----------------|-----------------------|-------------
UriTypeDefault | default | :8100 | ALL | /user/show-list | main.(*User).ShowList |
-----------------|---------|---------|--------|-----------------|-----------------------|-------------
SERVER | DOMAIN | ADDRESS | METHOD | ROUTE | HANDLER | MIDDLEWARE
------------------|---------|---------|--------|----------------|-----------------------|-------------
UriTypeFullName | default | :8200 | ALL | /User/ShowList | main.(*User).ShowList |
------------------|---------|---------|--------|----------------|-----------------------|-------------
SERVER | DOMAIN | ADDRESS | METHOD | ROUTE | HANDLER | MIDDLEWARE
------------------|---------|---------|--------|----------------|-----------------------|-------------
UriTypeAllLower | default | :8300 | ALL | /user/showlist | main.(*User).ShowList |
------------------|---------|---------|--------|----------------|-----------------------|-------------
SERVER | DOMAIN | ADDRESS | METHOD | ROUTE | HANDLER | MIDDLEWARE
---------------|---------|---------|--------|----------------|-----------------------|-------------
UriTypeCamel | default | :8400 | ALL | /user/showList | main.(*User).ShowList |
---------------|---------|---------|--------|----------------|-----------------------|------------- 可以分別訪問(wèn)以下URL地址得到期望的結(jié)果:
http://127.0.0.1:8100/user/show-list
http://127.0.0.1:8200/User/ShowList
http://127.0.0.1:8300/user/showlist
http://127.0.0.1:8400/user/showList
對(duì)象方法注冊(cè)
假如控制器中有若干公開(kāi)方法,但是我只想注冊(cè)其中幾個(gè),其余的方法我不想對(duì)外公開(kāi),怎么辦?我們可以通過(guò)?BindObject?傳遞第三個(gè)非必需參數(shù)替換實(shí)現(xiàn),參數(shù)支持傳入多個(gè)方法名稱,多個(gè)名稱以英文,號(hào)分隔(方法名稱參數(shù)區(qū)分大小寫(xiě))。
示例:
package main
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
)
type Controller struct{}
func (c *Controller) Index(r *ghttp.Request) {
r.Response.Write("index")
}
func (c *Controller) Show(r *ghttp.Request) {
r.Response.Write("show")
}
func main() {
s := g.Server()
c := new(Controller)
s.BindObject("/object", c, "Show")
s.SetPort(8199)
s.Run()
}執(zhí)行后,終端輸出路由表為:
SERVER | DOMAIN | ADDRESS | METHOD | ROUTE | HANDLER | MIDDLEWARE
|---------|---------|---------|--------|--------------|-------------------------|------------|
default | default | :8199 | ALL | /object/show | main.(*Controller).Show |
|---------|---------|---------|--------|--------------|-------------------------|------------|
綁定路由方法
我們可以通過(guò)?BindObjectMethod?方法綁定指定的路由到指定的方法執(zhí)行(方法名稱參數(shù)區(qū)分大小寫(xiě))。
?BindObjectMethod?和?BindObject?的區(qū)別:?BindObjectMethod?將對(duì)象中的指定方法與指定路由規(guī)則進(jìn)行綁定,第三個(gè)?method?參數(shù)只能指定一個(gè)方法名稱;?BindObject?注冊(cè)時(shí),所有的路由都是對(duì)象方法名稱按照規(guī)則生成的,第三個(gè)?methods?參數(shù)可以指定多個(gè)注冊(cè)的方法名稱。
來(lái)看一個(gè)例子:
package main
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
)
type Controller struct{}
func (c *Controller) Index(r *ghttp.Request) {
r.Response.Write("index")
}
func (c *Controller) Show(r *ghttp.Request) {
r.Response.Write("show")
}
func main() {
s := g.Server()
c := new(Controller)
s.BindObjectMethod("/show", c, "Show")
s.SetPort(8199)
s.Run()
}執(zhí)行后,終端輸出的路由表如下:
SERVER | DOMAIN | ADDRESS | METHOD | ROUTE | HANDLER | MIDDLEWARE
|---------|---------|---------|--------|-------|-------------------------|------------|
default | default | :8199 | ALL | /show | main.(*Controller).Show |
|---------|---------|---------|--------|-------|-------------------------|------------|
RESTful對(duì)象注冊(cè)
?RESTful?設(shè)計(jì)方式的控制器,通常用于?API?服務(wù)。在這種模式下,?HTTP?的?Method?將會(huì)映射到控制器對(duì)應(yīng)的方法名稱,例如:?POST?方式將會(huì)映射到控制器的?Post?方法中(公開(kāi)方法,首字母大寫(xiě)),?DELETE?方式將會(huì)映射到控制器的?Delete?方法中,以此類推。其他非?HTTP ?Method??命名的方法,即使是定義的包公開(kāi)方法,將不會(huì)自動(dòng)注冊(cè),對(duì)于應(yīng)用端不可見(jiàn)。當(dāng)然,如果控制器并未定義對(duì)應(yīng)?HTTP Method?的方法,該?Method?請(qǐng)求下將會(huì)返回 ?HTTP Status 404?。
?GoFrame?的這種?RESTful?對(duì)象注冊(cè)方式是一種嚴(yán)格的?REST?路由注冊(cè)方式,我們可以將控制器的對(duì)象看做?REST?中的資源,而其中的?HTTP Method?方法即為?REST?規(guī)范的資源操作方法。如果大家不太熟悉?REST?規(guī)范,或者不想太過(guò)嚴(yán)格的?RESTful?路由設(shè)計(jì),那么請(qǐng)忽略該章節(jié)。
我們可以通過(guò)?BindObjectRest?方法完成?REST?對(duì)象的注冊(cè),示例:
package main
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
)
type Controller struct{}
// RESTFul - GET
func (c *Controller) Get(r *ghttp.Request) {
r.Response.Write("GET")
}
// RESTFul - POST
func (c *Controller) Post(r *ghttp.Request) {
r.Response.Write("POST")
}
// RESTFul - DELETE
func (c *Controller) Delete(r *ghttp.Request) {
r.Response.Write("DELETE")
}
// 該方法無(wú)法映射,將會(huì)無(wú)法訪問(wèn)到
func (c *Controller) Hello(r *ghttp.Request) {
r.Response.Write("Hello")
}
func main() {
s := g.Server()
c := new(Controller)
s.BindObjectRest("/object", c)
s.SetPort(8199)
s.Run()
}執(zhí)行后,終端輸出路由表如下;
SERVER | DOMAIN | ADDRESS | METHOD | ROUTE | HANDLER | MIDDLEWARE
|---------|---------|---------|--------|---------|---------------------------|------------|
default | default | :8199 | DELETE | /object | main.(*Controller).Delete |
|---------|---------|---------|--------|---------|---------------------------|------------|
default | default | :8199 | GET | /object | main.(*Controller).Get |
|---------|---------|---------|--------|---------|---------------------------|------------|
default | default | :8199 | POST | /object | main.(*Controller).Post |
|---------|---------|---------|--------|---------|---------------------------|------------|
構(gòu)造方法Init與析構(gòu)方法Shut
對(duì)象中的?Init?和?Shut?是兩個(gè)在?HTTP?請(qǐng)求流程中被?Server?自動(dòng)調(diào)用的特殊方法(類似構(gòu)造函數(shù)和析構(gòu)函數(shù)的作用)。
Init回調(diào)方法
對(duì)象收到請(qǐng)求時(shí)的初始化方法,在服務(wù)接口調(diào)用之前被回調(diào)執(zhí)行。
方法定義:
// "構(gòu)造函數(shù)"對(duì)象方法
func (c *Controller) Init(r *ghttp.Request) {
}
Shut回調(diào)方法
當(dāng)請(qǐng)求結(jié)束時(shí)被?Server?自動(dòng)調(diào)用,可以用于對(duì)象執(zhí)行一些收尾處理的操作。
方法定義:
// "析構(gòu)函數(shù)"對(duì)象方法
func (c *Controller) Shut(r *ghttp.Request) {
}舉個(gè)例子:
package main
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
)
type Controller struct{}
func (c *Controller) Init(r *ghttp.Request) {
r.Response.Writeln("Init")
}
func (c *Controller) Shut(r *ghttp.Request) {
r.Response.Writeln("Shut")
}
func (c *Controller) Hello(r *ghttp.Request) {
r.Response.Writeln("Hello")
}
func main() {
s := g.Server()
c := new(Controller)
s.BindObject("/object", c)
s.SetPort(8199)
s.Run()
}執(zhí)行后,終端輸出路由表如下:
SERVER | DOMAIN | ADDRESS | METHOD | ROUTE | HANDLER | MIDDLEWARE
|---------|---------|---------|--------|---------------|--------------------------|------------|
default | default | :8199 | ALL | /object/hello | main.(*Controller).Hello |
|---------|---------|---------|--------|---------------|--------------------------|------------|可以看到,并沒(méi)有自動(dòng)注冊(cè)?Init?和?Shut?這兩個(gè)方法的路由,我們?cè)L問(wèn) http://127.0.0.1:8199/object/hello 后,輸出結(jié)果為:
Init
Hello
Shut 本文標(biāo)題:創(chuàng)新互聯(lián)GoFrame教程:GoFrame路由注冊(cè)-對(duì)象注冊(cè)
當(dāng)前地址:http://m.5511xx.com/article/ccddjig.html


咨詢
建站咨詢
