[TOC]
# 簡介
支持3種形式的路由
1. 函數注冊級別的restful路由
2. control級別的注冊自動化的映射
3. 更自由化的handle注冊,只要實現了ServeHTTP(response, request)函數的都可以
前面是包名,后面是方法,第三個參數是你指定方法
`/:?id`表示傳遞參數
~~~
func init() {
beego.Router("/", &controllers.MainController{})
beego.Router("/user", &controllers.UserController{})
beego.Router("/user/info/?:id", &controllers.UserController{}, "get:GetInfo")
}
~~~
對應controllers包下面的我創建個文件user.go就這樣寫
~~~
import (
"github.com/astaxie/beego"
)
type UserController struct {
beego.Controller
}
func (c *UserController) GetInfo() {
c.Ctx.WriteString("hello world---111-----\n")
id := c.Ctx.Input.Param(":id")
c.Ctx.WriteString("getInfo data, id = "+id)
}
~~~
如果想要post的話就這樣指定
~~~
beego.Router("/user/info", &controllers.UserController{}, "get:GetInfo;post:PostInfo")
~~~
# 重定向
把/index.html實際指向到/static/html/+
~~~
func main() {
ignoreStaticPath()
beego.Run()
}
//重定向
func ignoreStaticPath() {
//沒有匹配到的
beego.InsertFilter("/", beego.BeforeRouter, TransparentStatic)
//匹配所有的
beego.InsertFilter("/*", beego.BeforeRouter, TransparentStatic)
}
func TransparentStatic(ctx *context.Context) {
//"github.com/astaxie/beego/context" 導入這個包
orpath := ctx.Request.URL.Path
beego.Debug("request url: ", orpath)
//如果請求url還有api字段,說明指令應該取消靜態資源路徑重定向
if (strings.Index(orpath, "api") >= 0) {
return
}
//"net/http"
//重定向到 /static/html/+ 這個路徑
http.ServeFile(ctx.ResponseWriter, ctx.Request, "static/html/"+ctx.Request.URL.Path)
}
~~~
# 正則路由
~~~
/**
41 * 正則路由實踐
42 */
43
44 /**
45 * 正則路由實踐
46 * 注意事項:1. 第二個參數需要傳遞一個控制器:Controller
47 * 2. 【?:id】 中的id也可以換成其他字符,如:【?:abc】
48 * 測試用例:能 匹 配:/api ; /api/123 ; /api/abc ; /api/abc.html ; /api/abc/
49 不能匹配:/api/123/456 :即/api/之后只能再接一個參數
50 * 輸出結果:具體輸出結果需要看第二個參數的Get()方法所指定的模板和數據。
51 */
52 beego.Router("/api/?:id", &controllers.MainController{})
53
54 /**
55 * 正則路由實踐
56 * 注意事項:【:id】前面沒有了 ?
57 * 測試用例:能 匹 配:/api/123 ; /api/abc ; /api/abc.html ; /api/abc/
58 不能匹配:/api ; /api/123/456 :即/api/之后只能再接一個參數
59 * 輸出結果:具體輸出結果需要看第二個參數的Get()方法所指定的模板和數據。
60 */
61 beego.Router("/api/:id", &controllers.MainController{})
62
63 /**
64 * 正則路由實踐
65 * 注意事項:【:id】前面沒有了 ?
66 * 測試用例:能 匹 配:/api/123 ; /api/0
67 不能匹配:/api ; /api/123/456 ; /api/abc ; /api/123.html
68 * 輸出結果:具體輸出結果需要看第二個參數的Get()方法所指定的模板和數據。
69 */
70 beego.Router("/api/:id:int", &controllers.MainController{})
71
72 /**
73 * 正則路由實踐
74 * 注意事項::id([0-9]+) 之中有個 + 號。有+號時表示可以是多位數字,無+號表示就只能匹配一位數字
75 * 測試用例:能 匹 配:/api/123 ; /api/0
76 不能匹配:/api ; /api/abc ; /api/123/456 :即/api/之后只能再接一個參數
77 * 輸出結果:具體輸出結果需要看第二個參數的Get()方法所指定的模板和數據。
78 */
79 beego.Router("/api/:id([0-9]+)", &controllers.MainController{})
80
81 /**
82 * 正則路由實踐
83 * 注意事項::[\\w] 之中的w不能替換為別的字符
84 * 測試用例:能 匹 配:/api/123 ; /api/hezhixiong
85 不能匹配:/api ; /api/abc.html
86 * 輸出結果:具體輸出結果需要看第二個參數的Get()方法所指定的模板和數據。
87 */
88 beego.Router("/api/:username([\\w]+)", &controllers.MainController{})
89
90 /**
91 * 正則路由實踐
92 * 注意事項:: :username:string表示 username為string型
93 * 測試用例:能 匹 配:/api/123 ; /api/hezhixiong
94 不能匹配:/api ; /api/abc.html
95 * 輸出結果:具體輸出結果需要看第二個參數的Get()方法所指定的模板和數據。
96 */
97 beego.Router("/api/:username:string", &controllers.MainController{})
98
99 /**
100 * 正則路由實踐
101 * 注意事項::無
102 * 測試用例:能 匹 配:/api/123 ; /api/hezhixiong ; /api/abc.html ; /api/abc/123/efg/ddd
103 不能匹配:/api
104 * 輸出結果:具體輸出結果需要看第二個參數的Get()方法所指定的模板和數據。
105 */
106 beego.Router("/api/*.*", &controllers.MainController{})
107
108 /**
109 * 正則路由實踐
110 * 注意事項::無
111 * 測試用例:能 匹 配:/api/123 ; /api/hezhixiong ; /api/abc.html ; /api/abc/123/efg/ddd
112 不能匹配:/api
113 * 輸出結果:具體輸出結果需要看第二個參數的Get()方法所指定的模板和數據。
114 */
115 beego.Router("/api/*", &controllers.MainController{})
116
117 /**
118 * 正則路由實踐
119 * 注意事項::無
120 * 測試用例:能 匹 配:/api/bei_123.html ; /api/bei_0.html
121 不能匹配:/api/bei_.html ; /api/bei_123 ; /api/bei_12a.html
122 * 輸出結果:具體輸出結果需要看第二個參數的Get()方法所指定的模板和數據。
123 */
124 beego.Router("/api/bei_:id([0-9]+).html", &controllers.MainController{})
~~~
# 函數級別的注冊
~~~
beego.Get(router, beego.FilterFunc)
beego.Post(router, beego.FilterFunc)
//任何方式
beego.Any(router, beego.FilterFunc)
~~~
~~~
beego.Get("/", func(c *context.Context) {
c.Output.Body([]byte("---------------"))
})
~~~
參數路由適用于函數和control設置,解析后的數據可以在`ctx.Input.Param()`獲取
# 映射路由
~~~
beego.Router("/user/info", &Restcontrollers{}, "*:GetInfo")
beego.Router("/user/info", &Restcontrollers{}, "get,post:GetInfo")
beego.Router("/user/info", &Restcontrollers{}, "get:GetInfo;post:GetInfo")
~~~
# 自動化路由
~~~
beego.AutoRouter(&controllers.ObjectController{})
~~~
請求映射如下:
~~~
/object/login 調用ObjectController中的Login方法
~~~
除了前綴兩個`/:controller/:method`的匹配外,剩下的url,beego會幫你解析為參數,保存在`this.Ctx.Input.Param`當中:
~~~
/object/blog/2013/03/5 調用ObjectController中的Blog方法,參數如下:map[0:2013, 1:03, 2:5]
~~~
~~~
/object/LOGIN 也是解析到Login方法
~~~
自動化路由之API解析
現在可以自動化解析下面的url,把請求分發給controller下面的simple方法
~~~
/controller/simple
/controller/simple.json
/controller/simple.html
/controller/simple.rss
~~~
可以通過`this.Ctx.Input.Param(":ext")`獲取后綴名
# 注解路由
beego 自動會進行源碼分析,注意只會在 dev 模式下進行生成,生成的路由放在 `/routers/`
用戶無需在 router 中注冊路由,只需要 Include 相應地 controller,然后在 controller 的 method 方法上面寫上 router 注釋(// @router)就可以了,詳細的使用請看下面的例子:
~~~
// CMS API
type CMSController struct {
beego.Controller
}
func (c *CMSController) URLMapping() {
c.Mapping("StaticBlock", c.StaticBlock)
c.Mapping("AllBlock", c.AllBlock)
}
// @router /staticblock/:key [get]
func (this *CMSController) StaticBlock() {
}
// @router /all/:key [get]
func (this *CMSController) AllBlock() {
}
~~~
可以在`router.go`中通過如下方式注冊路由:
~~~
beego.Include(&CMSController{})
~~~
beego 自動會進行源碼分析,注意只會在 dev 模式下進行生成,生成的路由放在 “/routers/commentsRouter.go” 文件中。
這樣上面的路由就支持了如下的路由:
* GET /staticblock/:key
* GET /all/:key
其實效果和自己通過 Router 函數注冊是一樣的:
~~~
beego.Router("/staticblock/:key", &CMSController{}, "get:StaticBlock")
beego.Router("/all/:key", &CMSController{}, "get:AllBlock")
~~~
對應控制器
~~~
// CMS API
type CMSController struct {
beego.Controller
}
func (c *CMSController) URLMapping() {
c.Mapping("StaticBlock", c.StaticBlock)
c.Mapping("AllBlock", c.AllBlock)
}
// @router /staticblock/:key1 [get]
func (this *CMSController) StaticBlock() {
this.Ctx.WriteString("hello world---112211-----\n")
key1 := this.Ctx.Input.Param(":key1")
this.Ctx.WriteString("getInfo data, key = "+key1)
}
// @router /all/:key1 [get]
func (this *CMSController) AllBlock() {
}
~~~
# 命名空間
**cond**
~~~
Cond(cond namespaceCond)
~~~
看域名是不是這個api.beego.me不是就給404
~~~
ns:=NewNamespace("/v1")
ns.Cond(func(ctx *context.Context) bool {
//判斷域名
if ctx.Input.Domain() == "api.beego.me" {
return true
}
return false
})
~~~
# 多模塊
多模塊使用namespace,然后引用的地方注冊
~~~
beego.AddNamespace(ns)
~~~
~~~
//shop model
shop := NewNamespace("/shop")
//order model
order := NewNamespace("/order")
min.go
beego.AddNamespace(shop, order)
~~~
~~~
/**
184 * namespace路由實踐
185 * 注意事項:必須要把NewNamespace的對象注冊到AddNamespace中去,否則無效
186 * 測試用例:僅僅匹配:/aaa/go
187 * 輸出結果:get請求的情況下,執行指定函數Login;其他HTTP method則按照RESTful規則
188 */
189 ns_1 := beego.NewNamespace("aaa", beego.NSRouter("/go", &controllers.MainController{}, "get:Login"))
190 // beego.AddNamespace(ns_1)
191
192 /**
193 * 域名如果不是:127.0.0.1,則不可以匹配 /bbb/go
194 * 僅僅匹配:/bbb/go
195 */
196 ns_2 := beego.NewNamespace("bbb",
197 beego.NSCond(func(ctx *context.Context) bool {
198 if ctx.Input.Domain() == "127.0.0.1" {
199 return true
200 }
201 return false
202 }),
203 beego.NSRouter("/go", &controllers.MainController{}, "get:Login"),
204 )
205
206 ns_3 := beego.NewNamespace("ccc",
207 beego.NSRouter("/go", &controllers.MainController{}, "get:Login"),
208 // 條件判斷,如果為真,則可以匹配上下文的路由,如果為假,則上下文的路由都不能匹配
209 beego.NSCond(func(ctx *context.Context) bool {
210 if ctx.Input.Domain() == "127.0.0.1" {
211 return true
212 }
213 return false
214 }),
215 beego.NSRouter("php", &controllers.MainController{}),
216 beego.NSGet("java", func(ctx *context.Context) {
217 ctx.Output.Body([]byte("顯示Get追加的內容"))
218 }),
219
220 // nasespace嵌套示例
221 beego.NSNamespace("room",
222 beego.NSCond(func(ctx *context.Context) bool {
223 // 如果子namespace的判斷條件為假,那么僅僅是子namespace的url不能匹配,不影響夫namespace的匹配結果
224 if ctx.Input.Request.Method != "GET" {
225 return true
226 }
227 return false
228 }),
229 beego.NSRouter("/shanghai", &controllers.MainController{}), // 匹配地址:/ccc/room/shanghai
230 ),
231 )
232
233 beego.AddNamespace(ns_1, ns_2, ns_3)
234 }
~~~
# 定義的 handler
有些時候我們已經實現了一些 rpc 的應用,但是想要集成到 beego 中,或者其他的 httpserver 應用,集成到 beego 中來.現在可以很方便的集成:
~~~
s := rpc.NewServer()
s.RegisterCodec(json.NewCodec(), "application/json")
s.RegisterService(new(HelloService), "")
beego.Handler("/rpc", s)
~~~
`beego.Handler(router, http.Handler)`這個函數是關鍵,第一個參數表示路由 URI, 第二個就是你自己實現的`http.Handler`, 注冊之后就會把所有 rpc 作為前綴的請求分發到`http.Handler`中進行處理.
這個函數其實還有第三個參數就是是否是前綴匹配,默認是 false, 如果設置了 true, 那么就會在路由匹配的時候前綴匹配,即`/rpc/user`這樣的也會匹配去運行
~~~
beego.Handler("/rpc", s, true)
~~~
# 跨域
~~~
beego.InsertFilter("*", beego.BeforeRouter, cors.Allow(&cors.Options{
AllowOrigins: []string{"*"},
AllowMethods: []string{"GET", "PUT", "PATCH", "POST"},
AllowHeaders: []string{"Origin", "Authorization", "Access-Control-Allow-Origin", "Access-Control-Allow-Headers", "Content-Type", "token"},
ExposeHeaders: []string{"Content-Length"},
AllowCredentials: true}))
~~~
- 基礎
- 簡介
- 主要特征
- 變量和常量
- 編碼轉換
- 數組
- byte與rune
- big
- sort接口
- 和mysql類型對應
- 函數
- 閉包
- 工作區
- 復合類型
- 指針
- 切片
- map
- 結構體
- sync.Map
- 隨機數
- 面向對象
- 匿名組合
- 方法
- 接口
- 權限
- 類型查詢
- 異常處理
- error
- panic
- recover
- 自定義錯誤
- 字符串處理
- 正則表達式
- json
- 文件操作
- os
- 文件讀寫
- 目錄
- bufio
- ioutil
- gob
- 棧幀的內存布局
- shell
- 時間處理
- time詳情
- time使用
- new和make的區別
- container
- list
- heap
- ring
- 測試
- 單元測試
- Mock依賴
- delve
- 命令
- TestMain
- path和filepath包
- log日志
- 反射
- 詳解
- plugin包
- 信號
- goto
- 協程
- 簡介
- 創建
- 協程退出
- runtime
- channel
- select
- 死鎖
- 互斥鎖
- 讀寫鎖
- 條件變量
- 嵌套
- 計算單個協程占用內存
- 執行規則
- 原子操作
- WaitGroup
- 定時器
- 對象池
- sync.once
- 網絡編程
- 分層模型
- socket
- tcp
- udp
- 服務端
- 客戶端
- 并發服務器
- Http
- 簡介
- http服務器
- http客戶端
- 爬蟲
- 平滑重啟
- context
- httptest
- 優雅中止
- web服務平滑重啟
- beego
- 安裝
- 路由器
- orm
- 單表增刪改查
- 多級表
- orm使用
- 高級查詢
- 關系查詢
- SQL查詢
- 元數據二次定義
- 控制器
- 參數解析
- 過濾器
- 數據輸出
- 表單數據驗證
- 錯誤處理
- 日志
- 模塊
- cache
- task
- 調試模塊
- config
- 部署
- 一些包
- gjson
- goredis
- collection
- sjson
- redigo
- aliyunoss
- 密碼
- 對稱加密
- 非對稱加密
- 單向散列函數
- 消息認證
- 數字簽名
- mysql優化
- 常見錯誤
- go run的錯誤
- 新手常見錯誤
- 中級錯誤
- 高級錯誤
- 常用工具
- 協程-泄露
- go env
- gometalinter代碼檢查
- go build
- go clean
- go test
- 包管理器
- go mod
- gopm
- go fmt
- pprof
- 提高編譯
- go get
- 代理
- 其他的知識
- go內存對齊
- 細節總結
- nginx路由匹配
- 一些博客
- redis為什么快
- cpu高速緩存
- 常用命令
- Go 永久阻塞的方法
- 常用技巧
- 密碼加密解密
- for 循環迭代變量
- 備注
- 垃圾回收
- 協程和纖程
- tar-gz
- 紅包算法
- 解決golang.org/x 下載失敗
- 逃逸分析
- docker
- 鏡像
- 容器
- 數據卷
- 網絡管理
- 網絡模式
- dockerfile
- docker-composer
- 微服務
- protoBuf
- GRPC
- tls
- consul
- micro
- crontab
- shell調用
- gorhill/cronexpr
- raft
- go操作etcd
- mongodb