我的基本main设置:
muxRouter := mux.NewRouter()
v1Router.Router(muxRouter.PathPrefix("/v1").Subrouter())
http.Handle("/", muxRouter)
n := negroni.Classic()
n.Use(negroni.HandlerFunc(apiRouter.Middleware))
n.UseHandler(muxRouter)
s := &http.Server{
Addr: ":6060",
Handler: n,
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
MaxHeaderBytes: 1 << 20,
}
log.Fatal(s.ListenAndServe())在apiRouter.Middleware中,我设置了以下上下文:
context.Set(req, helperKeys.DomainName, "some-value")但是,在v1Router.Router中的某些handlerFunc中,当尝试Get上下文值时,结果为nil:
domain := context.Get(req, helperKeys.DomainName)
fmt.Println("DomainName", domain)印刷品:DomainName <nil>
我知道Set方法是正确的,因为在apiRouter.Middleware中设置后立即获取值将返回正确的字符串值。
发布于 2017-02-15 00:27:05
我最终使用了内置在Context中的Go 1.7
context.Set(req, helperKeys.DomainName, "some-value")
// Replaced with:
ctx := req.Context()
ctx = context.WithValue(ctx, helperKeys.DomainName, "some-value")
req = req.WithContext(ctx)和
domain := context.Get(req, helperKeys.DomainName)
// Replaced with:
domain := req.Context().Value(helperKeys.DomainName).(string)发布于 2017-02-15 02:23:47
根据您的回答,看起来您正在尝试在上下文中存储数据库。我不建议这样做。相反,尝试如下所示:
type Something struct {
DB *sql.DB // or some other DB object
}
func (s *Something) CreateUser(w http.ResponseWriter, r *http.Request) {
// use s.DB to access the database
fmt.Fprintln(w, "Created a user...")
}
func main() {
db := ...
s := Something{db}
http.HandleFunc("/", s.CreateUser)
// ... everything else is pretty much like normal.
}这使您的处理程序可以访问数据库,而不必每次都在上下文中设置它。上下文值应该保留给那些直到运行时才可能设置的内容。例如,特定于该web请求的请求ID。存在时间超过请求的事物通常不属于这一类,并且您的DB连接将存在于请求之外。
如果您确实需要上下文值,则应该:
使用typed
下面显示了一个这样的示例,我将更多地讨论this blog post中的一般上下文值
type userCtxKeyType string
const userCtxKey userCtxKeyType = "user"
func WithUser(ctx context.Context, user *User) context.Context {
return context.WithValue(ctx, userCtxKey, user)
}
func GetUser(ctx context.Context) *User {
user, ok := ctx.Value(userCtxKey).(*User)
if !ok {
// Log this issue
return nil
}
return user
}https://stackoverflow.com/questions/42229594
复制相似问题