beego中设置路由的几种方式

  1. beego中设置路由的几种方式
    1. 基础路由
    2. 固定路由
    3. 正则路由
    4. 自定义方法及RESTful规则
    5. 自动匹配
    6. 注解路由
    7. namespace

beego中设置路由的几种方式

基础路由、固定路由、正则路由的请求方法名是默认的,如Get、Post、Delete、Patch等。其余的路由可以自定义方法名。

以下示例代码均已上传 github

基础路由

//get路由
beego.Get("/", func(ctx *context.Context) {
   ctx.Output.Body([]byte("hello get"))
})

//post路由
beego.Post("/", func(ctx *context.Context) {
   ctx.Output.Body([]byte("hello post"))
})

//可以响应任何http的路由,假如上文中Get和Set都不存在的话,那么get和set请求都会进入该方法
beego.Any("/", func(ctx *context.Context) {
   ctx.Output.Body([]byte("hello any"))
})

访问时,根据请求属性,进入对应的函数,除了上述函数以外,还有Put,Patch,Head,Options,Delete等。例如在postman中发送如下请求:

返回:

hello any

固定路由

以固定的请求路径对应到固定的Controller中

beego.Router("/",MainController{})
beego.Router("/test",TestController{})
beego.Router("/v1/test",V1TestController{})

例如路由注册为:

beego.Router("/v1/person", &controllers.Test1Controller{})

对应的controller代码如下:

type Test1Controller struct {
    beego.Controller
}

var persons = make(map[string]string)

func (p *Test1Controller) Post() {
    name := p.GetString("name")
    age := p.GetString("age")
    persons[name] = age
    p.Data["json"] = "ok"
    p.ServeJSON()
}

func (p *Test1Controller) Get() {
    name := p.GetString("name")
    age := persons[name]
    p.Data["json"] = age
    p.ServeJSON()
}

发送post请求:

http://localhost:8080/v1/person?name=zhangsan&age=18

再发送get请求:

http://localhost:8080/v1/person?name=zhangsan

正则路由

1,/api_2/123可以匹配成功,变量”:id”值为”123”

beego.Router("/api_2/?:id", &controllers.Test2Controller{})

发送get请求:

http://localhost:8080/api/123

controller代码如下:

type Test2Controller struct {
   beego.Controller
}

func (p *Test2Controller) Any() {
   id := p.Ctx.Input.Param(":id")
   fmt.Println(id)
   p.Data["json"] = id
   p.ServeJSON()
}

2,/api_3/123可以匹配成功,变量”:id”值为”123”,不匹配/api/

beego.Router("/api_3/:id", &controllers.Test3Controller{})

controller代码同上

3,匹配 /api_4/123,变量”:id”值为”123”,不匹配/api_4/

beego.Router("/api_4/:id([0-9]+)", &controllers.Test4Controller{})

controller代码同上

以下正则匹配与前文类似,不再一一举例。

//正则字符串匹配,/user/astaxie,变量":username"值为astaxie
beego.Router("/user/:username([\\w]+)", &controllers.Test2Controller{})
//*匹配方式,/download/file/api.xml,变量":path"值为"file/api",变量":ext"值为"xml"
beego.Router("/download/*.*", &controllers.Test2Controller{})
//*全匹配方式,/download/ceshi/file/api.json,变量":splat"值为"file/api.json"
beego.Router("/download/ceshi/*", &controllers.Test2Controller{})
//int 类型设置方式,":id"为int类型,框架帮你实现了正则([0-9]+)
beego.Router("/:id:int", &controllers.Test2Controller{})
//string类型设置方式,":hi"为string类型,框架帮你实现了正则([\w]+)
beego.Router("/:hi:string", &controllers.Test2Controller{})
//带有前缀的自定义正则,":id"为正则类型。匹配 cms_123.html这样的url,":id"值为"123"
beego.Router("/cms_:id([0-9]+).html", &controllers.Test2Controller{})

可以在 Controller 中通过如下方式获取上面的变量:

p.Ctx.Input.Param(":id")
p.Ctx.Input.Param(":username")
p.Ctx.Input.Param(":splat")
p.Ctx.Input.Param(":path")
p.Ctx.Input.Param(":ext")

自定义方法及RESTful规则

beego.Router("/test5",&controllers.Test5Controller{},"*:TestMethod")

第三个参数用来设置对应的请求method到方法名,*表示通配,定义如下:

  • *表示任意的 method 都执行该函数
  • 使用 httpmethod:funcname 格式来展示
  • 多个不同的格式使用 ; 分割
  • 多个 method 对应同一个 funcname,method 之间通过 , 来分割

示例:

beego.Router("/api/list",&RestController{},"*:ListFood")
//post方法指向CreateFood
beego.Router("/api/create",&RestController{},"post:CreateFood")
//put指向UpdateFood
beego.Router("/api/update",&RestController{},"put:UpdateFood")
//get和post均指向ApiFunc
beego.Router("/api",&RestController{},"get,post:ApiFunc")
//不同的 method 对应不同的函数,通过;进行分割
beego.Router("/simple",&SimpleController{},"get:GetFunc;post:PostFunc")

可用的http Method:

  • *包含以下所有的函数
  • get: GET 请求
  • post: POST 请求
  • put: PUT 请求
  • delete: DELETE 请求
  • patch: PATCH 请求
  • options: OPTIONS 请求
  • head: HEAD 请求

如果同时存在 * 和对应的 HTTP Method,那么优先执行 HTTP Method 的方法。

自动匹配

首先需要把需要路由的控制器注册到自动路由中:

beego.AutoRouter(&controllers.Test6Controller{})

beego 就会通过反射获取该结构体中所有的实现方法,你就可以通过如下的方式访问到对应的方法中:

http://localhost:8080/test6/testmethod/2333/zhangsan

除了前缀两个 /:controller/:method 的匹配之外,剩下的 url beego 会自动解析为参数,保存在 this.Ctx.Input.Params 当中,controller代码如下:

func (p *Test6Controller) TestMethod() {
   mp := p.Ctx.Input.Params()
   id := mp["0"]
   name := mp["1"]
   fmt.Printf("0: %v,1: %v \n", id, name)
   p.Data["json"] = id
   p.ServeJSON()
}

控制台打印内容:

0: 2333,1: zhangsan

可以通过自动识别出来下面类似的所有 url,都会把请求分发到 controllertest 方法:

/controller/test
/controller/test.html
/controller/test.json
/controller/test.xml

可以通过 this.Ctx.Input.Param(":ext") 获取后缀名。

注解路由

从 beego 1.3 版本开始支持了注解路由,用户无需在 router 中注册路由,只需要 Include 相应地 controller,然后在 controller 的 method 方法上面写上 router 注释(@router)就可以了,举例:

可以在 router.go 中通过如下方式注册路由

beego.Include(&controllers.Test7Controller{})

controller:

type Test7Controller struct {
   beego.Controller
}

func (p *Test7Controller) URLMapping() {
   p.Mapping("method1", p.TestMethod1)
   p.Mapping("method2", p.TestMethod2)
}

// @router /method1/:key [get]
func (p *Test7Controller) TestMethod1() {
   p.Data["json"] = "method1"
   p.ServeJSON()
}

// @router /method2/:key [post]
func (p *Test7Controller) TestMethod2() {
   p.Data["json"] = "method2"
   p.ServeJSON()
}

beego 自动会进行源码分析,注意只会在 dev 模式下进行生成,生成的路由放在 routers/commentsRouter.go文件中:

func init() {

    beego.GlobalControllerRouter["github.com/beego_router/controllers:Test7Controller"] = append(beego.GlobalControllerRouter["github.com/beego_router/controllers:Test7Controller"],
        beego.ControllerComments{
            Method: "TestMethod1",
            Router: `/method1/:key`,
            AllowHTTPMethods: []string{"get"},
            MethodParams: param.Make(),
            Filters: nil,
            Params: nil})

    beego.GlobalControllerRouter["github.com/beego_router/controllers:Test7Controller"] = append(beego.GlobalControllerRouter["github.com/beego_router/controllers:Test7Controller"],
        beego.ControllerComments{
            Method: "TestMethod2",
            Router: `/method2/:key`,
            AllowHTTPMethods: []string{"post"},
            MethodParams: param.Make(),
            Filters: nil,
            Params: nil})

}

效果和自己通过 Router 函数注册是一样的:

beego.Router("/method1/:key", &CMSController{}, "get:TestMethod1")
beego.Router("/method2/:key", &CMSController{}, "post:TestMethod2")

支持了如下的路由:

  • GET /method1/:key
  • SET /method2/:key

注意:按照上述路由配置方式,如果请求连接中不带参数会找不到路由。如果要避免,在注册路由的时候就不要加上参数”:key”。

namespace

namespace的用法很多,且可以和其他的路由方式配合使用,在这里给出一个例子。

router.go:

ns1 := beego.NewNamespace("/v1",
   beego.NSNamespace("/version",
      beego.NSInclude(
         &controllers.Test8Controller{},
      ),
   ),
)
ns2 := beego.NewNamespace("/v2",
   beego.NSInclude(
      &controllers.Test9Controller{},
   ),
)
beego.AddNamespace(ns1, ns2)

common_router.go:

func init() {
   beego.GlobalControllerRouter["github.com/beego_router/controllers:Test8Controller"] = append(beego.GlobalControllerRouter["github.com/beego_router/controllers:VersionController"],
      beego.ControllerComments{
         Method:           "TestMethod8",
         Router:           ``,
         AllowHTTPMethods: []string{"get"},
         MethodParams:     param.Make(),
         Filters:          nil,
         Params:           nil})
   beego.GlobalControllerRouter["github.com/beego_router/controllers:Test9Controller"] = append(beego.GlobalControllerRouter["github.com/beego_router/controllers:TransactionForAndroidController"],
      beego.ControllerComments{
         Method:           "TestMethod9",
         Router:           `/transaction`,
         AllowHTTPMethods: []string{"get"},
         MethodParams:     param.Make(),
         Filters:          nil,
         Params:           nil})
}

test8_controller.go:

type Test8Controller struct {
   beego.Controller
}

func (p *Test8Controller) URLMapping() {
   p.Mapping("test8", p.TestMethod8)
}

func (p *Test8Controller) TestMethod8() {
   p.Data["json"] = "method8"
   p.ServeJSON()
}

test9_controller.go:

func (p *Test9Controller) URLMapping() {
   p.Mapping("method9", p.TestMethod9)
}

func (p *Test9Controller) TestMethod9() {
   p.Data["json"] = "method9"
   p.ServeJSON()
}

请求路径:

http://localhost:8080/v1/version
http://localhost:8080/v2/transaction

namespace的运用可以很灵活,建议所有的路由都使用同一种规则,在项目组成员相互协作的时候更加方便。


转载请注明来源

×

喜欢就点赞,疼爱就打赏