如何在上下文中访问键

时间:2018-12-31 14:17:51

标签: go

第一个例子

我正在使用chi路由器(github.com/go-chi/chi)和以下简单的默认代码:

func main() {
    router := chi.NewRouter()

    router.Group(func(subrouter chi.Router) {

        subrouter.Use(AddContext)

        subrouter.Get("/", func(w http.ResponseWriter, r *http.Request) {
            ctx := r.Context()

            routeContext := ctx.Value("RouteContext")
            test := ctx.Value("myContextTestKey")

            fmt.Printf("ctx: %+v\n", ctx)
            fmt.Printf("routeContext: %+v\n", routeContext)
            fmt.Printf("test: %+v\n", test)
        })
    })

    srv := &http.Server{
        Addr:    ":" + Port,
        Handler: router,
    }
    err := srv.ListenAndServe()
    CheckErr(err)
}

func AddContext(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        ctx := context.WithValue(r.Context(), "myContextTestKey", "myContextTestValue")
        next.ServeHTTP(w, r.WithContext(ctx))
    })
}

如果我Printf,这就是我的情况:

ctx: context.Background

.WithValue(&http.contextKey{name:"http-server"}, &http.Server{Addr:":3000", Handler:(*chi.Mux)(0xc0002f8840), TLSConfig:(*tls.Config)(0xc000430300), ReadTimeout:0, ReadHeaderTimeout:0, WriteTimeout:0, IdleTimeout:0, MaxHeaderBytes:0, TLSNextProto:map[string]func(*http.Server, *tls.Conn, http.Handler){"h2":(func(*http.Server, *tls.Conn, http.Handler))(0x78b450)}, ConnState:(func(net.Conn, http.ConnState))(nil), ErrorLog:(*log.Logger)(nil), disableKeepAlives:0, inShutdown:0, nextProtoOnce:sync.Once{m:sync.Mutex{state:0, sema:0x0}, done:0x1}, nextProtoErr:error(nil), mu:sync.Mutex{state:0, sema:0x0}, listeners:map[*net.Listener]struct {}{(*net.Listener)(0xc0001222b0):struct {}{}}, activeConn:map[*http.conn]struct {}{(*http.conn)(0xc000149680):struct {}{}, (*http.conn)(0xc000160460):struct {}{}}, doneChan:(chan struct {})(nil), onShutdown:[]func(){(func())(0x7972c0)}})

.WithValue(&http.contextKey{name:"local-addr"}, &net.TCPAddr{IP:net.IP{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1}, Port:3000, Zone:""}).WithCancel.WithCancel

.WithValue(&chi.contextKey{name:"RouteContext"}, &chi.Context{Routes:(*chi.Mux)(0xc0002f8840), RoutePath:"", RouteMethod:"GET", RoutePatterns:[]string{"/"}, URLParams:chi.RouteParams{Keys:[]string(nil), Values:[]string(nil)}, routePattern:"/", routeParams:chi.RouteParams{Keys:[]string(nil), Values:[]string(nil)}, methodNotAllowed:false})

.WithValue("myContextTestKey", "myContextTestValue")

第二个示例

使用github.com/volatiletech/authboss,我正在尝试使用以下代码访问上下文:

router.Use(ab.LoadClientStateMiddleware)

router.Group(func(subrouter chi.Router) {
    subrouter.Use(authboss.Middleware2(ab, 1, 1))
    subrouter.Get("/", func(w http.ResponseWriter, r *http.Request) {
        if user := r.Context().Value("user"); user != nil {
            fmt.Println(user.(auth.User))
        } else {
            fmt.Println("Still nil")
        }
    }
}

从这张图片中可以看到:

debugging

user在这里。

问题

1)为什么我不能用r.Context().Value("user")? Why always nil访问它?

2)为什么我得到nil的{​​{1}}并正确获得routeContext var的myContextTestValue

3)如何在上下文中读取其他键?

注意:仅test并没有这个问题,我无法理解如何在上下文中访问密钥。我知道我必须在chi router中使用相同类型的密钥,但是如何知道以前的类型?

0 个答案:

没有答案