go的http中间件接口问题

发布于 2022-09-11 18:30:29 字数 1852 浏览 27 评论 0

通常,http的中间件使用函数方式

 func M1(next http.Handler) http.Handler {
     return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
         log.Println("M1 in")
         next.ServeHTTP(w, r)
         log.Println("M1 out")
     })
 }

 func M2(next http.Handler) http.Handler {
     return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
         log.Println("M2 in")
         next.ServeHTTP(w, r)
         log.Println("M2 out")
     })
 }

func final(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("OK"))
}

func main() {
    finalHandler := http.HandlerFunc(final)
    http.Handle("/", M1(M2(finalHandler)))
    http.ListenAndServe(":8080", nil)
}

但这样写不够灵活,比如我要在中间件中依赖其它对象或者想抽象一些方法时不好处理。于是,我想用对象并约定一个中间件接口的方式来使用中间件

type Middleware interface {
    Handler(next http.Handler) http.Handler
}
type M1 struct {
    Id string
}
type M2 struct {
}
func (this *M1) Handler(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        log.Println("M1 in")
        log.Printf("M1=%v", this)
        this.Id = "hello"
        next.ServeHTTP(w, r)
        log.Println("M1 out")
    })
}
func (this *M2) Handler(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        log.Println("M2 in")
        next.ServeHTTP(w, r)
        log.Println("M2 out")
    })
}

func main() {
    finalHandler := http.HandlerFunc(final)
    m1 := &M1{}
    m2 := &M2{}
    http.Handle("/", m1.Handler(m2.Handler((finalHandler))))
    http.ListenAndServe(":8080", nil)
}

但这样做会有问题,因为m1,m2是在应用启动时初始化的,在不同的请求中,m1,m2指向的是同一个对象。

如例子所示,第一次请求时,m1的Id没有设置,这个时候打印的m1,Id为空。之后m1的Id被设置成hello,这样,第二次请求时,打印的m1,Id的值就是hello。

这个需求,怎么实现比较好?怎么样才能做到每个请求创建一个新的m1?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

泛滥成性 2022-09-18 18:30:29

可以参考echo里面的中间件JWT的思路,可以封装一个M1的函数,M1这个结构体可以在M1函数里面实现,这样就可以每次都是一个新的对象了。大概是这样:

func M1(next http.Handler) http.Handler {
    m1 := &M1{Id:"hello"}
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        log.Println("M1 in")
        log.Printf("M1=%v",m1)
        log.Printf("M1.Id=%v",m1.id)
        next.ServeHTTP(w, r)
        log.Println("M1 out")
    })
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文