[gin-gonic/gin]Context.Engine 应该为 Context.engine

2023-12-11 75 views
6

Context.Engine 应该为不可导出的深圳市出现以下代码

package main

import (
    "github.com/gin-gonic/gin"
    "net/http"
)

func main() {
    router := gin.Default()
    router.GET("/", func(c *gin.Context) {
        c.Engine.GET("/ping", func(c *gin.Context) { // Should not be
            c.String(http.StatusOK, "pong")
        })
    })

    router.Run(":8090")
}

回答

1

就像 v0.1 一样,Context.Engine 不会被导出。在上下文中.go

type Context struct {
    engine    *Engine
}
3

我不同意这一点。从 Context 访问 Engine 非常有用,特别是对于 HTML 模板。我将路线处理程序保存在单独的包中。

        tmpl := template.Must(template.ParseFiles("main.tmpl", "index.tmpl"))

        c.Engine.HTMLRender = render.HTMLRender{
                Template: tmpl,
        }

        c.HTML(200, "base", m.Result)
2

@techjanitor @420303865 这是一个棘手的问题。我不记得为什么将 context.Engine 设置为导出变量。

@techjanitor,你的代码可能看起来不错,但这太不安全了。您正在修改请求内的全局变量。如果您的应用程序配置为GOMAXPROCS> 0,则:

        tmpl := template.Must(template.ParseFiles("main.tmpl", "index.tmpl"))

        c.Engine.HTMLRender = render.HTMLRender{
                Template: tmpl,
        }
        // <<< here another request in a different thread could modify c.Engine.HTMLRender
        // even worse, two threads could modify the variable at the same time. and you get a race condition.
        c.HTML(200, "base", m.Result)

router.HTMLRender 应在开始时初始化,否则应c.Render直接使用。

// c.Render is stateless, so it is thread-safe
c.Render(200, render.HTML{
    Template: template.Must(template.ParseFiles("main.tmpl", "index.tmpl")),
    Name: "main.templ",
    Data: yourData,
})

或者直接使用模板:

tmpl := template.Must(template.ParseFiles("main.tmpl", "index.tmpl"))
c.Header("Content-Type", "text/html; charset=utf-8")
c.Writer.WriteHeader(200)
tmpl.ExecuteTemplate(c.Writer, "main.tmpl", yourData)
4

啊有趣,谢谢你的信息。我没有考虑使用c.Render。这可能是放在自述文件中的一个很好的例子。

5

是的!我可能会重命名c.Enginec.engine,这很容易出错。

问你@techjanitor:为什么你要尝试在每个请求中加载模板?我认为这是一项非常昂贵的手术。

2

因为我是一个糟糕的程序员;D

7

Annnnnd...我不知道如何获取 ,因为我无法从处理程序RouteInfo访问。engine

1

想要从处理程序获取 RoutesInfo,有什么想法吗?

2

谢谢@thinkerou 在询问之前我已经阅读了代码。我的意思是我无法从 gin.Context 获取 gin.Engine,因此我无法调用 RoutesInfo 方法。

3

@bbiao

func (h *handler) Test(c *gin.Context) {
    routeInfo := gin.RouteInfo{
        Method:      c.Request.Method,
        Path:        c.FullPath(),
        Handler:     c.HandlerName(),
        HandlerFunc: c.Handler(),
    }
    c.String(http.StatusOK, routeInfo.Handler)
}
2

@bbiao

func (h *handler) Test(c *gin.Context) {
  routeInfo := gin.RouteInfo{
      Method:      c.Request.Method,
      Path:        c.FullPath(),
      Handler:     c.HandlerName(),
      HandlerFunc: c.Handler(),
  }
  c.String(http.StatusOK, routeInfo.Handler)
}

谢谢,我已经使用最新的代码和 gin.Context.FullPath() 方法解决了我的问题。