如何在不使用 DefaultServeMux 的情况下实现 HandlerFunc

如果我要使用 DefaultServeMux(我通过将它nil作为第二个参数传递给 ListenAndServe 来指定它),那么我可以访问http.HandleFunc,您在下面的 Go wiki 示例中看到了它:


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

    fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:])

}


func main() {

    http.HandleFunc("/", handler)

    http.ListenAndServe(":8080", nil)

}

在我当前的代码中,我无法使用 DefaultServeMux,即我将自定义处理程序传递给 ListenAndServe


    h := &mypackage.Handler{

        Database: mydb

    }

    http.ListenAndServe(":8080", h)

所以我没有http.HandleFunc内置。但是,我必须将一些授权代码调整到我的代码库中,这些代码需要类似http.HandleFunc. 例如,如果我一直在使用 DefaultServeMux,当我点击"/protected"路由时,我会想去Protected处理程序,但只有在通过h.AuthorizationHandlerFunc这样的


   h.AuthorizationHandlerFunc(Protected)

但是,由于我没有使用 DefaultServeMux,因此它不起作用,即我无法将Protected函数(并调用它)传递给AuthorizationHandlerFunc. 这是下面 AuthorizationHandlerFunc 的实现。你可以在下面看到Protected永远不会被调用的。


问题:HandlerFunc在这种情况下如何实现(不使用 DefaultServeMux)?


func (h *Handler) AuthorizationHandlerFunc(next http.HandlerFunc) http.Handler{

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

         h.AuthorizationMiddleWare(w, r, next)

   })

}


func (h *Handler) AuthorizationMiddleWare(w http.ResponseWriter, r *http.Request, next http.HandlerFunc){

     //other stuff happens

     log.Println("this is never getting called")

     next(w,r)

}

func (h *Handler)Protected(w http.ResponseWriter, r *http.Request){


      log.Println("this is never getting called")

}

更新 ServeHTTP 在 mypackage.Handler 上实现。为什么 Protected 函数没有被调用,或者,AuthorizationMiddleWare 中的相关代码没有被调用?


守着星空守着你
浏览 169回答 1
1回答

智慧大石

将您的授权中间件重新实现为http.Handler:type auth struct {   DB *sql.DB   UnauthorizedHandler http.Handler}func NewAuth(db *sql.DB, unauthorized http.Handler) *auth {    return auth{db, unauthorized}}func (a *auth) Protected(h http.Handler) http.Handler {    fn := func(w http.ResponseWriter, r *http.Request) {        // Check whether the request is valid        // If it's invalid, call your error func and make sure to *return* early!        if !valid {            a.UnauthorizedHandler.ServeHTTP(w, r)            return        }        // Call the next handler on success        h.ServeHTTP(w, r)        return    }    return http.HandlerFunc(fn)}func someHandler(w http.ResponseWriter, r *http.Request) {    io.WriteString(w, "Hello!\n")}func main() {    auth := NewAuth(db, errorHandler)    r := http.NewServeMux()    // We have a http.Handler implementation that wraps a http.HandlerFunc    // ... so we call r.Handle on our ServeMux and type-cast the wrapped func    r.Handle("/protected", auth.Protected(http.HandlerFunc(someHandler)))    // Just a simple http.HandlerFunc here    r.HandleFunc("/public", someOtherHandler)    log.Fatal(http.ListenAndServe(":8000", r))}看看我为一个不同的例子编写的httpauth libServeHTTP方法。以上和ServeHTTP在您的类型上显式创建方法都是有效的方法。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go