第一个例子:
我正在使用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")
}
}
}
从这张图片中可以看到:
键user
在这里。
问题:
1)为什么我不能用r.Context().Value("user")? Why always
nil访问它?
2)为什么我得到nil
的{{1}}并正确获得routeContext
var的myContextTestValue
?
3)如何在上下文中读取其他键?
注意:仅test
并没有这个问题,我无法理解如何在上下文中访问密钥。我知道我必须在chi router
中使用相同类型的密钥,但是如何知道以前的类型?