“alice”未调用中间件



为什么这里只调用H1ServeHTTP方法,而忽略了H2H3的方法?

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")
}

您的中间件处理程序需要在准备好后调用下一个处理程序。未测试的示例:

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作为中间件的另一个例子。

每个中间件都传递一个您执行的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/

最新更新