# 封装路由器
你可以能永远用不上它,但是以防万一还是加入了这章内容。
有时,你可能需要覆盖或决定是否执行传入请求路由器。 如果你以前有过使用 net/http 包,和其他 web 框架的经验,那么你会熟悉此功能 (它有一个 net/http 中间件的形式,但它不接受下一个处理程序,而是接受路由器作为一个函数去要执行或不不执行)。
```
// WrapperFunc 用作 WrapRouter 预期输入参数签名
// 是兼容 net/http 的一个 "low-level" 签名
// 它用于根据自定义逻辑运行或不运行路由器。
type WrapperFunc func(w http.ResponseWriter, r *http.Request, router http.HandlerFunc)
// WrapRouter 在主路由器的顶部添加一个包装器。
// 通常对于第三方中间件很有用
// 需要使用像 CORS 这样的中间件包装整个应用程序时。
//
// 开发人员可以添加多个包装,
// 这些包装程序的执行从最后到第一个执行。
// 这意味着第二个包装器将包装第一个包装器,依此类推。
//
// 建立之前
func WrapRouter(wrapperFunc WrapperFunc)
```
路由器根据 `Subdomain`,HTTP `Method` 及其动态 `Path` 搜索其路由。路由器包装程序可以覆盖该行为并执行自定义代码。
在此示例中, 你只会看到 `.WrapRouter`的一个用例。你可以使用 `.WrapRouter` 添加何时或何时不应该执行路由器,以执行注册的路由的处理程序的自定义逻辑。 这只是为了概念验证,你可以跳过本教程。
示例代码:
```
package main
import (
"net/http"
"strings"
"github.com/kataras/iris/v12"
)
func newApp() *iris.Application {
app := iris.New()
app.OnErrorCode(iris.StatusNotFound, func(ctx iris.Context) {
ctx.HTML("<b>Resource Not found</b>")
})
app.Get("/profile/{username}", func(ctx iris.Context) {
ctx.Writef("Hello %s", ctx.Params().Get("username"))
})
app.HandleDir("/", "./public")
myOtherHandler := func(ctx iris.Context) {
ctx.Writef("inside a handler which is fired manually by our custom router wrapper")
}
// 用本地 net/http 处理程序包装路由器。
// 如果 url 不包含任何 "." (即: .css, .js...)
// (取决于应用程序,你可能需要添加更多文件服务器异常,
// 然后处理程序将执行负责
// 已注册的路由 (看上去是 "/" 和 "/profile/{username}")
// 如果没有, 则它将基于根 "/" 路径文件提供服务。
app.WrapRouter(func(w http.ResponseWriter, r *http.Request, router http.HandlerFunc) {
path := r.URL.Path
if strings.HasPrefix(path, "/other") {
// 获取并释放上下文以便使用它来执行
// 我们的自定义处理程序
// 记住:我们使用 net/http.Handler 是因为
// 我们在路由器本身之前处于“低级”状态。
ctx := app.ContextPool.Acquire(w, r)
myOtherHandler(ctx)
app.ContextPool.Release(ctx)
return
}
// 否则继续照常服务路由。
router.ServeHTTP(w, r)
})
return app
}
func main() {
app := newApp()
// http://localhost:8080
// http://localhost:8080/index.html
// http://localhost:8080/app.js
// http://localhost:8080/css/main.css
// http://localhost:8080/profile/anyusername
// http://localhost:8080/other/random
app.Run(iris.Addr(":8080"))
// 注意:在此示例中,我们只看到了一个用例,
// 你可能需要 .WrapRouter 或者 .Downgrade 才能
// 绕过Iris的默认路由器,即:
// 你也可以使用该方法来设置自定义代理。
}
```
这里没有什么需要赘述的,它只是一个函数包装程序,它接受本机响应编写器和请求, 而下一个处理程序是Iris的Router本身, 无论是否被调用,它都在执行,**它是整个路由器的中间件**。