感谢#go-nuts上的“
cronos”帮助,我设法解决了这一问题。
该解决方案允许我使用自定义处理程序类型,链中间件,并避免重复包装处理程序(即appHandler(myHandler),中间件…):
type appHandler func(http.ResponseWriter, *http.Request) *appErrortype appError struct { Code int Error error}func (fn appHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { if e := fn(w, r); e != nil { switch e.Code { case http.StatusNotFound: notFound(w, r) case http.StatusInternalServerError: serverError(w, r, e.Error, e.Code) default: serverError(w, r, e.Error, e.Code) } }}func use(h appHandler, middleware ...func(http.Handler) http.Handler) http.Handler { var res http.Handler = h for _, m := range middleware { res = m(res) } return res}func someMiddleware(h http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Cache-Control", "max-age=0, private, must-revalidate") w.Header().Set("X-Accel-Expires", "0") h.ServeHTTP(w, r) })}func myHandler(w http.ResponseWriter, r *http.Request) *appError { err := doSomething() if err != nil { return &appError{500, err} } // render your template, etc. return nil}路线如下所示:
r.Handle("/route", use(myHandler, someMiddleware))您显然可以进行修改
appHandler以返回所需的内容,并向其添加其他字段
appError等等。如果要将路由器应用于所有路由,则中间件也可以包装路由器-即
http.Handle("/",someMiddleware(r))


