🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# 封装路由器 你可以能永远用不上它,但是以防万一还是加入了这章内容。 有时,你可能需要覆盖或决定是否执行传入请求路由器。 如果你以前有过使用 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本身, 无论是否被调用,它都在执行,**它是整个路由器的中间件**。