如何将值从子中间件传播到父中间件?

我正在尝试通过中间件模式自定义请求管道,代码如下:


func helloHandler(w http.ResponseWriter, r *http.Request) {

    fmt.Println("Hello, middleware!")

}

func middleware1(next http.HandlerFunc) func(w http.ResponseWriter, r *http.Request) {

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

        fmt.Println("[START] middleware1")

        ctx := r.Context()

        ctx = context.WithValue(ctx, middleware1Key, middleware1Value)

        r = r.WithContext(ctx)

        next(w, r)

        fmt.Println("[END] middleware1")

        ctx = r.Context()

        if val, ok := ctx.Value(middleware2Key).(string); ok {

            fmt.Printf("Value from middleware2 %s \n", val)

        }


    }

}

func middleware2(next http.HandlerFunc) func(w http.ResponseWriter, r *http.Request) {

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

        fmt.Println("[START] middleware2")

        ctx := r.Context()

        if val, ok := ctx.Value(middleware1Key).(string); ok {

            fmt.Printf("Value from middleware1 %s \n", val)

        }

        ctx = context.WithValue(ctx, middleware2Key, middleware2Value)

        r = r.WithContext(ctx)

        next(w, r)

        fmt.Println("[END] middleware2")


    }

}

func main() {

    mux := http.NewServeMux()

    middlewares := newMws(middleware1, middleware2)

    mux.HandleFunc("/hello", middlewares.then(helloHandler))

    if err := http.ListenAndServe(":8080", mux); err != nil {

        panic(err)

    }


}

输出是:


[START] middleware1

[START] middleware2

Value from middleware1 middleware1Value

Hello, middleware!

[END] middleware2

[END] middleware1

根据输出,值可以从 parent 传递给 child ,而如果 child 添加一些东西到 context ,它对 parent 是不可见的


我如何将价值从子中间件传播到父中间件?


哈士奇WWW
浏览 128回答 1
1回答

白猪掌柜的

您正在做的是创建一个指向修改后的 http.Request viaWithContext方法的新指针。因此,如果您将它传递给链中的下一个中间件,一切都会按预期工作,因为您将这个新指针作为参数传递。如果要修改请求并使其对持有指向它的指针的人可见,则需要取消引用指针并设置修改后的值。所以在你的“孩子”中间件而不是:r = r.WithContext(ctx)只需执行以下操作:*r = *r.WithContext(ctx)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go