ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、视频、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
File: routing/custom-context/method-overriding/main.go ~~~ package main // 在本包中,我将向您展示如何覆盖现有上下文的功能和方法. // 您可以轻松导航到自定义上下文示例,以了解如何添加新功能 // 你自己的 (need a custom handler). // // 这种方式更容易理解,并且当您想要覆盖现有方法时它更快: import ( "reflect" "github.com/kataras/iris" "github.com/kataras/iris/context" ) // 创建自己的自定义上下文,放置您需要的任何字段. type MyContext struct { //可选第1部分:嵌入(可选但如果您不想覆盖所有上下文的方法,则需要) context.Context // 它是context / context.go #context struct,但你不需要知道它. } var _ context.Context = &MyContext{} // 可选:如果MyContext实现context.Context,则在编译时验证. // 如果您将覆盖Context,那么唯一重要的一个 // 嵌入的context.Context里面. // 需要通过此“* MyContext”运行处理程序. func (ctx *MyContext) Do(handlers context.Handlers) { context.Do(ctx, handlers) } //第二个是重要的,如果你将覆盖上下文 // 嵌入的context.Context里面. // 通过此“* MyContext”运行处理程序链所必需的. func (ctx *MyContext) Next() { context.Next(ctx) } // 覆盖您想要的任何上下文方法... // [...] func (ctx *MyContext) HTML(htmlContents string) (int, error) { ctx.Application().Logger().Infof("Executing .HTML function from MyContext") ctx.ContentType("text/html") return ctx.WriteString(htmlContents) } func main() { app := iris.New() // app.Logger().SetLevel("debug") // 他只有一个必需: // 以下是您如何定义自己的上下文的方式 //从iris的通用上下文池中创建和获取. app.ContextPool.Attach(func() context.Context { return &MyContext{ // Optional Part 3: Context: context.NewContext(app), } }) //在./view/**目录中的.html文件上注册视图引擎. app.RegisterView(iris.HTML("./view", ".html")) // 像往常一样注册您的路线 app.Handle("GET", "/", recordWhichContextJustForProofOfConcept, func(ctx context.Context) { // use the context's overridden HTML method. ctx.HTML("<h1> Hello from my custom context's HTML! </h1>") }) //这将由MyContext.Context执行 //如果MyContext没有直接定义View函数. app.Handle("GET", "/hi/{firstname:alphabetical}", recordWhichContextJustForProofOfConcept, func(ctx context.Context) { firstname := ctx.Values().GetString("firstname") ctx.ViewData("firstname", firstname) ctx.Gzip(true) ctx.View("hi.html") }) app.Run(iris.Addr(":8080")) } //应始终打印“($ PATH)处理程序正在从'MyContext'执行” func recordWhichContextJustForProofOfConcept(ctx context.Context) { ctx.Application().Logger().Infof("(%s) Handler is executing from: '%s'", ctx.Path(), reflect.TypeOf(ctx).Elem().Name()) ctx.Next() } //查看“new-implementation”以了解如何使用新功能创建全新的Context. ~~~ File: routing/custom-context/method-overriding/view/hi.html ~~~ <h1> Hi {{.firstname}} </h1> ~~~ File: routing/custom-context/new-implementation/main.go ~~~ package main import ( "sync" "github.com/kataras/iris" "github.com/kataras/iris/sessions" ) // 所有者是我们的应用程序结构,它包含我们需要的方法或字段, // 认为它是我们* Context的拥有者. type Owner struct { //在这里定义全局字段 // 并分享给所有客户. sessionsManager *sessions.Sessions } // 这个包级变量“application”将在上下文中用于与我们的全局Application通信. var owner = &Owner{ sessionsManager: sessions.New(sessions.Config{Cookie: "mysessioncookie"}), } // Context是我们的自定义上下文. // 让我们实现一个允许我们访问的上下文 // 通过一个简单的`ctx.Session()`调用到客户端的Session. type Context struct { iris.Context session *sessions.Session } //会话返回当前客户端的会话. func (ctx *Context) Session() *sessions.Session { // 如果我们在同一个处理程序中多次调用`Session()`,这对我们有帮助 if ctx.session == nil { // 如果之前没有创建,则启动新会话. ctx.session = owner.sessionsManager.Start(ctx.Context) } return ctx.session } // Bold将向客户端发送粗体文本. func (ctx *Context) Bold(text string) { ctx.HTML("<b>" + text + "</b>") } var contextPool = sync.Pool{New: func() interface{} { return &Context{} }} func acquire(original iris.Context) *Context { ctx := contextPool.Get().(*Context) ctx.Context = original // 将上下文设置为原始上下文,以便访问iris的实现. ctx.session = nil //重置会话 return ctx } func release(ctx *Context) { contextPool.Put(ctx) } // Handler会将我们的func(* Context)处理程序转换为iris处理程序, // 为了与HTTP API兼容. func Handler(h func(*Context)) iris.Handler { return func(original iris.Context) { ctx := acquire(original) h(ctx) release(ctx) } } func newApp() *iris.Application { app := iris.New() // 像以前一样工作,唯一的区别 // 是原始的context.Handler应该用我们的自定义包装 // `Handler` function. app.Get("/", Handler(func(ctx *Context) { ctx.Bold("Hello from our *Context") })) app.Post("/set", Handler(func(ctx *Context) { nameFieldValue := ctx.FormValue("name") ctx.Session().Set("name", nameFieldValue) ctx.Writef("set session = " + nameFieldValue) })) app.Get("/get", Handler(func(ctx *Context) { name := ctx.Session().GetString("name") ctx.Writef(name) })) return app } func main() { app := newApp() // GET: http://localhost:8080 // POST: http://localhost:8080/set // GET: http://localhost:8080/get app.Run(iris.Addr(":8080")) } ~~~ File: routing/custom-context/new-implementation/main_test.go ~~~ package main import ( "testing" "github.com/kataras/iris/httptest" ) func TestCustomContextNewImpl(t *testing.T) { app := newApp() e := httptest.New(t, app, httptest.URL("http://localhost:8080")) e.GET("/").Expect(). Status(httptest.StatusOK). ContentType("text/html"). Body().Equal("<b>Hello from our *Context</b>") expectedName := "iris" e.POST("/set").WithFormField("name", expectedName).Expect(). Status(httptest.StatusOK). Body().Equal("set session = " + expectedName) e.GET("/get").Expect(). Status(httptest.StatusOK). Body().Equal(expectedName) } ~~~