Go httprouter 自定义中间件

作为一名 Go 程序员,我相对较新,我正在尝试为我的服务器构建一个自定义中间件。问题是它的行为不像我预期的那样。有人可以解释为什么我的上下文没有设置为ME吗?


package main


import (

    "context"

    "log"

    "net/http"


    "github.com/julienschmidt/httprouter"

)


func main() {

    router := httprouter.New()

    router.GET("/test", middlewareChain(contentType, name))

    log.Print("App running on 8080")

    log.Fatal(http.ListenAndServe(":8080", router))

}


func middlewareChain(h ...httprouter.Handle) httprouter.Handle {

    return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {

        r = r.WithContext(context.WithValue(r.Context(), "test", "You"))

        log.Print("Set context to YOU")

        for _, handler := range h {

            handler(w, r, p)

        }

    }

}


func contentType(w http.ResponseWriter, r *http.Request, p httprouter.Params) {

    r = r.WithContext(context.WithValue(r.Context(), "test", "Me"))

    log.Print("Set context to ME")

    header := w.Header()

    header.Set("Content-type", "application/json")

}


func name(w http.ResponseWriter, r *http.Request, p httprouter.Params) {

    log.Printf("Context: %s", r.Context().Value("test"))

}

http://img3.mukewang.com/6266681f0001131609980427.jpg

犯罪嫌疑人X
浏览 138回答 1
1回答

互换的青春

如果中间件与下一个相关联,我发现它们最有用。堆栈中稍后的中间件可以依赖先前设置的值,因此它们是顺序相关的。有时,他们可以决定在某种条件下停止堆栈。像这样把它们锁起来怎么样?func main() {    router := httprouter.New()    router.GET("/test", setTestYou(contentType(name)))    log.Print("App running on 8080")    log.Fatal(http.ListenAndServe(":8080", router))}func setTestYou(next httprouter.Handle) httprouter.Handle {    return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {        r = r.WithContext(context.WithValue(r.Context(), "test", "You"))        log.Print("Set context to YOU")        if next != nil {            next(w, r, p)        }    }}func contentType(next httprouter.Handle) httprouter.Handle {    return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {        if r.Header.Get("Content-type") != "application/json" {            // break here instead of continuing the chain            w.Status = 400            return        }        r = r.WithContext(context.WithValue(r.Context(), "test", "Me"))        log.Print("Set context to ME")        header := w.Header()        header.Set("Content-type", "application/json")        if next != nil {            next(w, r, p)        }    }}func name(w http.ResponseWriter, r *http.Request, p httprouter.Params) {    log.Printf("Context: %s", r.Context().Value("test"))}由于他们将请求/上下文传递到下一个,因此更改将保持不变。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go