当前位置: 首页 > 面试题库 >

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

袁子瑜
2023-03-14
问题内容

如果我要使用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中调用相关代码?


问题答案:

将您的授权中间件重新实现为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))
}

Take a look at the httpauth lib I
wrote
for a
different example with a ServeHTTP method. Both the above and explicitly
creating a ServeHTTP method on your type are valid approaches.



 类似资料:
  • 问题内容: 以下App Engine处理程序在可以获取令牌的范围内起作用: 当连接到模板时,它会从Facebook获得令牌响应并愉快地显示它。但是,最好不要将用户重定向到example.com/?state=SOME_UNIQUE_VALUE&code=AQB0iYpAf8nMmX5blahblah# = 来完成登录。 有没有一种方法可以使用client.Get等来访问授权URL,遵循重​​定向,

  • 在我的情况下,登录应用程序时需要通过UID从realTime Database获取用户配置文件 在文档中必须使用添加值事件通知程序才能从实时数据库读取 //如果我有obj的id,如何直接从实时firebase获取值 //我的问题是,这里不能使用这种方法

  • 我有一个简单的Quarkus资源: 我试图将实例注入到我的资源中,但是我得到了一个。但是,如果我在上使用注释,那么一切都很好。是否有一种方法可以在不使用注释的情况下将类注入到我的资源中?换句话说,是否有一种方法可以使Quakus容器可以发现而不直接注释该类? 编辑:查看CDI文档,似乎可以使用带有注释的方法手动注册bean。但是,我不清楚哪个类应该包含带注释的方法) 另一个选择是使用Jandex索

  • 问题内容: 是否可以在不实现Comparable类的情况下使用Comparator?例如,如果我有以下内容: 然后可以使用comp比较两个对象吗?如果是这样,我将如何去做? 谢谢… 问题答案: 你不用。您使用。 是由对象实现的接口,用于指定它们与相同类型的其他对象的排序顺序。 是一个通用接口,只需要两个对象并告诉您它们的排序顺序。因此,您可以执行以下操作: 与: 和:

  • 问题内容: 我想知道是否有一种方法可以在不使用内置函数的情况下实现SQL分析功能。 问题答案: 这是三个等效的表达式: 假设存在,以使行对于“ row_number”而言是唯一的。

  • 我在运行时通过我的应用程序中的提供注入服务接口的实现。 最近,一个协作团队中的某个人创建了同一服务接口的另一个实现,并且该类被添加到了一个jar中,这是我在应用程序中无法避免的。因此,这会引发,我可以通过生产者方法和注入点上的CDI限定符来解决该异常。我想问一下是否有其他方法可以避免这种开销。我可以使用我的方法作为默认实现,使容器忽略第二个实现吗?我在producer方法上添加了注释和注释,以检查