使用julienschmidt/httprouter时连接中间件的最佳方法是什么?
就我用Google搜索而言,http.HandlerFunc只接受表单中的func (w ResponseWriter, r *Request)函数,而httprouter.Handle函数则是这种形式func (w http.ResponseWriter, r *http.Request, ps httprouter.Params).
如何在不将httprouter.Handle函数转换为http.HandlerFunc的情况下链接中间件?
例如:
我的routes.go是形式,
router := httprouter.New()
router.POST("/api/user/create", middlewares.EscapeStringsMiddleware(User.CreateUser))
log.Fatal(http.ListenAndServe(":8000", router))
Run Code Online (Sandbox Code Playgroud)
如何为上述路由编写中间件函数?
已经尝试过的方法:
1.
func EscapeStringsMiddleware(next http.Handler) httprouter.Handle {
return func (response http.ResponseWriter, request *http.Request, ps httprouter.Params) {
err := request.ParseForm()
if err != nil {
panic(err)
}
for key, values := range request.Form {
for i, value := range values {
value = template.HTMLEscapeString(value)
value = template.JSEscapeString(value)
request.Form[key][i] = value
}
}
next.ServeHTTP(response, request)
}
}
Run Code Online (Sandbox Code Playgroud)
获得的错误:
cannot use User.CreateUser (type func(http.ResponseWriter, *http.Request, httprouter.Params)) as type http.Handler in argument to middlewares.EscapeStringsMiddleware:
func(http.ResponseWriter, *http.Request, httprouter.Params) does not implement http.Handler (missing ServeHTTP method)
Run Code Online (Sandbox Code Playgroud)
2.
func EscapeStringsMiddleware(next httprouter.Handle) httprouter.Handle {
return func (response http.ResponseWriter, request *http.Request, ps httprouter.Params) {
err := request.ParseForm()
if err != nil {
panic(err)
}
for key, values := range request.Form {
for i, value := range values {
value = template.HTMLEscapeString(value)
value = template.JSEscapeString(value)
request.Form[key][i] = value
}
}
next.ServeHTTP(response, request)
}
}
Run Code Online (Sandbox Code Playgroud)
获得的错误:
next.ServeHTTP undefined (type httprouter.Handle has no field or method ServeHTTP)
Run Code Online (Sandbox Code Playgroud)
另外我如何链接多个中间件?
例如,
router.POST("/api/user/create", middlewares.VerifyCSRF(middlewares.EscapeStringsMiddleware(User.CreateUser)))
Run Code Online (Sandbox Code Playgroud)
R M*_*nke 12
此问题不适用于您的中间件处理程序.你是犯错误的,因为User.CreateUser不是类型http.Handler.
试试这种模式:
最重要的一点是要返回http.Handler,敷func(w http.ResponseWriter, r *http.Request)用http.HandlerFunc.
func Handler() http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// do stuff
})
}
Run Code Online (Sandbox Code Playgroud)
去源:
// The HandlerFunc type is an adapter to allow the use of
// ordinary functions as HTTP handlers. If f is a function
// with the appropriate signature, HandlerFunc(f) is a
// Handler that calls f.
type HandlerFunc func(ResponseWriter, *Request)
// ServeHTTP calls f(w, r).
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
f(w, r)
}
Run Code Online (Sandbox Code Playgroud)
根据您的反馈:
httprouter.Handle没有实现ServeHTTP.它是直接调用的.例如 :next(w, r, ps)
您将在下面找到中间件处理程序的示例.
// Middleware without "github.com/julienschmidt/httprouter"
func StdToStdMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// do stuff
next.ServeHTTP(w, r)
})
}
// Middleware for a standard handler returning a "github.com/julienschmidt/httprouter" Handle
func StdToJulienMiddleware(next http.Handler) httprouter.Handle {
return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
// do stuff
next.ServeHTTP(w, r)
}
}
// Pure "github.com/julienschmidt/httprouter" middleware
func JulienToJulienMiddleware(next httprouter.Handle) httprouter.Handle {
return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
// do stuff
next(w, r, ps)
}
}
func JulienHandler() httprouter.Handle {
return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
// do stuff
}
}
func StdHandler() http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// do stuff
})
}
func main() {
router := httprouter.New()
router.POST("/api/user/create", StdToJulienMiddleware(StdHandler()))
router.GET("/api/user/create", JulienToJulienMiddleware(JulienHandler()))
log.Fatal(http.ListenAndServe(":8000", router))
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3463 次 |
| 最近记录: |