英文:
Middleware Not Getting Called by `alice`
问题
为什么这里只调用了H1
的ServeHTTP
方法,而H2
和H3
的方法似乎被忽略了?
alice
似乎是一个很好的中间件链式调用库,我尝试将其与httprouter
一起使用,但只有最外层/最后一个中间件被调用:
package main
import (
"fmt"
"github.com/julienschmidt/httprouter"
"github.com/justinas/alice"
"net/http"
"log"
"time"
)
func main() {
fmt.Println("started ", time.Now())
c := alice.New(S1, S2, S3).Then(nil)
router := httprouter.New()
router.Handler("GET", "/app", c)
http.ListenAndServe(":27007", router)
}
func S1(h http.Handler) http.Handler {
var x H1
return &x
}
func S2(h http.Handler) http.Handler {
var x H2
return &x
}
func S3(h http.Handler) http.Handler {
var x H3
return &x
}
type H1 struct{}
func (h *H1) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
log.Println("H1", time.Now())
}
type H2 struct{}
func (h *H2) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
log.Println("H2")
}
type H3 struct{}
func (h *H3) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
log.Println("H3")
}
在这段代码中,只有H1
的ServeHTTP
方法被调用,而H2
和H3
的方法似乎被忽略了。
英文:
Why only ServeHTTP
method of H1
is getting called here and those of H2
and H3
seem to be ignored?
alice seems to be a nice middleware chaining and here I've tried to use it with httprouter, but only the outer/last middleware is getting called:
package main
import (
"fmt"
"github.com/julienschmidt/httprouter"
"github.com/justinas/alice"
"net/http"
"log"
"time"
)
func main() {
fmt.Println("started ", time.Now())
c := alice.New(S1, S2, S3).Then(nil)
router := httprouter.New()
router.Handler("GET", "/app", c)
http.ListenAndServe(":27007", router)
}
func S1(h http.Handler) http.Handler {
var x H1
return &x
}
func S2(h http.Handler) http.Handler {
var x H2
return &x
}
func S3(h http.Handler) http.Handler {
var x H3
return &x
}
type H1 struct{}
func (h *H1) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
log.Println("H1", time.Now())
}
type H2 struct{}
func (h *H2) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
log.Println("H2")
}
type H3 struct{}
func (h *H3) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
log.Println("H3")
}
答案1
得分: 1
你的中间件处理程序在准备好时需要调用下一个处理程序。未经测试的示例:
func S1(h http.Handler) http.Handler {
return &H1{next: h}
}
type H1 struct{
next http.Handler
}
func (h *H1) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
log.Println("H1", time.Now())
h.next.ServeHTTP(rw, req)
}
或者:
func S1(next http.Handler) http.Handler {
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
log.Println("H1", time.Now())
next(rw, req)
})
}
在 http://golang.org/src/net/http/server.go?s=37638:37688#L1280 上查看另一个中间件的示例。
英文:
Your middleware handlers need to call the next handler when ready. Untested example:
func S1(h http.Handler) http.Handler {
return &H1{next: h}
}
type H1 struct{
next http.Handler
}
func (h *H1) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
log.Println("H1", time.Now())
h.next.ServeHTTP(rw, req)
}
Or:
func S1(next http.Handler) http.Handler {
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
log.Println("H1", time.Now())
next(rw, req)
})
}
Look at http://golang.org/src/net/http/server.go?s=37638:37688#L1280 for another example of middleware.
答案2
得分: 0
每个中间件都会传递一个http.Handler
结构,你可以执行它。这样每个中间件就不需要知道处理程序的顺序,它们只需要关注执行链中的下一个处理程序。顺序是在初始化Alice时定义的。参考:
- http://adampresley.com/2015/02/08/using-a-middleware-in-your-go-web-applications.html
- https://justinas.org/alice-painless-middleware-chaining-for-go/
英文:
Each middleware is passed an http.Handler
structure that you execute. This allows each middleware to not know the order of handlers, and they only concern themselves with simply executing the next one in the chain. Order is defined when you initiate Alice. See:
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论