打包 Router
打包 Router
你也许永远也用不到这个特性,但是在极少情况下,你不得不使用它。
有时你需要覆盖某个路由,抑或是根据收到的请求决定是否使用这个路由。 如果你以前有过使用 net / http
和其他web框架的经验, 这个函数你会很熟悉(它和net / http
中间件的格式相同,但不能接受下一个处理程序,而是接受Router
作为函数 是否被执行)。
// WrapperFunc 用作预期的输入参数签名。
//用于 WrapRouter。 它是一个“低级”签名,与 net / http 兼容。
// 它用于运行或不运行基于自定义逻辑的路由器。
type WrapperFunc func(w http.ResponseWriter, r *http.Request, firstNextIsTheRouter http.HandlerFunc)
// WrapRouter 方法在主路由的顶部添加一个包装器
// 通常,它对第三方中间件非常有用
//比如,当需要使用 CORS 这样的中间件去包装整个应用程序的时候。
// 开发者可以添加多个包装器,
// 这些包装器是从后向前执行的。
//这意味着第二个包装器会封装第一个包装器,依此类推。
// 在构建之前。
func WrapRouter(wrapperFunc WrapperFunc)
Iris
的路由器基于HTTP方法搜索其路由,路由器包装器可以覆盖该行为并执行自定义代码。
示例代码:
package main
import (
"net/http"
"strings"
"github.com/kataras/iris"
)
//在这个实例中,你可以看到一个使用 WrapRouter 的例子.
// 当路由器执行或者不执行已经注册的路由处理程序的时候,你可以使用 WrapRouter 添加自定义的逻辑。
// 如何不使用自定义封装器,直接在根目录 "/" 启动服务。请查看 "file-server/single-page-application" 示例。
//这教程只是为了证明观点,如果它对你来说太多了,你可以跳过这个教程。
func main() {
app := iris.New()
app.OnErrorCode(iris.StatusNotFound, func(ctx iris.Context) {
ctx.HTML("<b>Resource Not found</b>")
})
app.Get("/", func(ctx iris.Context) {
ctx.ServeFile("./public/index.html", false)
})
app.Get("/profile/{username}", func(ctx iris.Context) {
ctx.Writef("Hello %s", ctx.Params().Get("username"))
})
// 如果我们使用了 “/” 指向服务根目录。
//静态网站将会覆盖所有路由,因为下划线需要通配符。
// 在这里,我们将看到如何绕过这种行为。
//通过创建新的文件服务
//和为路由器建立一个包装器(就像一个低优先级中间件),
//去手动检查路由器是否正常的处理
//和执行文件服务器的处理程序。
// 使用 StaticHandler 方法和 StaticWeb 一样,
//但它没有注册路由,它只返回了处理程序。
fileServer := app.StaticHandler("./public", false, false)
// 用本地 net/http 处理程序包装路由器。
// 如果 url 不包含任何 "." 符号。 (如: .css, .js...)
// (取决应用程序,你可以需要添加更多的文件服务器异常),
// 那么,处理程序将执行为路由器服务的已经注册的路由 (查找 "/" 和 "/profile/{username}")
//如果没有注册的路由,那么它将使用 “/” 根目录作为服务路径。
app.WrapRouter(func(w http.ResponseWriter, r *http.Request, router http.HandlerFunc) {
path := r.URL.Path
// 注意,如果路径具有 "index.html" 后缀,它将自动重定向到 “/” 路径。
// 所以我们的第一个处理程序将被执行。
if !strings.Contains(path, ".") {
// 如果它不是一个资源,则继续执行 router 方法。
router(w, r)
return
}
// 获取和释放上下文 ,用来执行我们的文件服务器。
// 记住:我们使用 net/http.Handler 因为在路由器之前,我们是在一个 比较低的优先级。
ctx := app.ContextPool.Acquire(w, r)
fileServer(ctx)
app.ContextPool.Release(ctx)
})
// http://localhost:8080
// http://localhost:8080/index.html
// http://localhost:8080/app.js
// http://localhost:8080/css/main.css
// http://localhost:8080/profile/anyusername
app.Run(iris.Addr(":8080"))
// 注意:在这个例子中,我们只使用了一个用例,
// 你可能想使用 WrapRouter 或者 Downgrade 来代替 iris 默认的路由, 例如:
//你可以使用此方法设置自定义代理。
//
//如果只想在其他路径上,而不是根目录上提供静态文件 ,你可以使用 StaticWeb方法。 例如:
// .StaticWeb("/static", "./public")
// ________________________________requestPath, systemPath
}
到这里已经介绍的差不多了,它只是一个接受本地响应编定器和请求的函数包装器,下一个处理程序是 iris
的 Router
本身, 不管调用与否,它都正执行或者不执行,它是整个 Router
的中间件。
本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
推荐文章: