程序员社区

Go:HTTP Handlers揭秘

Go:HTTP Handlers揭秘插图

net/http包使用Hanlders来处理对应路径的HTTP请求。在深入这个包内部可以发现里面定义了好几种方法和类型来处理请求,对于初学者来说有点迷惑。本文将对Go中的Handler做一个简单的介绍。

最重要的是有一个Handler接口。Handler接口是interface类型的,包含一个ServerHTTP方法,该方法包含两个参数:http.ResponseWriter和http.Request。

type Handler interface { ServeHTTP(ResponseWriter, *Request) }

这个方法可以说是响应请求的核心方法。我们在一个自定义结构体中实现ServerHTTP这个方法。

type helloWorldhandler struct
func (h helloWorldHandler) ServeHTTP(w ResponseWriter, r *Request){
     fmt.Fprintf(w,"HeloWorld")
}

然后使用http.Handle()函数将一个路径映射到给定的Handler上。

func Handle(pattern string, handler Handler)

当这个方法被调用,Go将给定的Handler注册到对应的路径,并且当对应路径的请求过来就会调用对应Handler的ServerHTTP函数。

http.Handler("/helloWorld",helloWorldHandler)

在这个例子中,当服务端请求路径是“/helloWorld”就会触发,helloWorldHandler的ServeHTTP方法会被调用。

上面这种处理HTTP请求方法的一个不好的地方就是,如果我们要处理不同路径的请求时,我们需要为每个路径都创建一个Handler类型来实现Handler接口。为了解决这个问题,net/http包提供了一个特殊的函数HandleFunc。

func HandleFunc(pattern string, handler func(ResponseWriter, *Request))

HandleFunc的作用和http.Hand(w, r)一样,注册一个handler到一个路径上,但实现的方式不同。如果你看下上面函数的签名,会发现,第二个参数是一个函数,而http.Handle()第二个参数是Handler类型。

因此,根据Go语言的特点,我们可以传入任意函数作为参数给http.HandleFunc(),只要参数签名符合func(ResponseWriter, *Request)格式即可。它将使用传入的函数来处理对应路径的请求。因此就消除了为每个路径都创建一个handler类型的困扰。

myHelloWorldFunc := func (w ResponseWriter, r *Request)
{fmt.Fprintf(w,"HeloWorld Function")}
http.HandleFunc("/helloWorld", myHelloWorldFunc)

最后就是HandlerFunc类型。该类型可以看作是一个适配器,可以实现普通函数作为http.Handler。
如果你看下这个函数类型的定义:

type HandlerFunc func(ResponseWriter, *Request)

可以看到HandlerFunc是一种函数类型。HandlerFunc类型本身实现了ServerHTTP方法,如下所示:

type HandlerFunc func(ResponseWriter, *Request)
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
    f(w,r)
}

因此,我们可以说HandlerFunc类型本身就实现了http.Handler接口。正如上面所看到的,我们仔细看ServeHTTP函数的实现,所做的就是调用HandlerFunc函数本身f对象。我们看个例子:

myHelloWorldFunc2 := func (w ResponseWriter, r *Request){
    fmt.Fprintf(w,"HeloWorld Function")
}
handlerFromHelloFunc := http.HandlerFunc(myHelloWorldFunc2)

http.Handle("/helloWorld", handlerFromHelloFunc)

从上面的例子可以看出,经过http.HandlerFunc函数转换后,myHelloWorldFunc2函数被转成http.Handler类型了。然后以一个普通handler类型参数,传给http.Handle方法。

这篇文章的目的是简单介绍net/http包各种实现处理请求的handler方法。总结一下,我们讨论了如何处理给定路径的HTTP请求的3种主要方法。
1、创建一个Handler类型,实现ServeHTTP方法,然后使用http.Handle(path, Handler)注册。
2、创建一个签名为func(w ResponseWriter, r *Request)函数,然后使用http.HandleFunc(path, function)来注册。
3、创建一个函数并使用http.HandlerFunc支持的类型来将其转换为一个Handler类型,并使用http.Handle(path, handler)注册。

赞(0) 打赏
未经允许不得转载:IDEA激活码 » Go:HTTP Handlers揭秘

一个分享Java & Python知识的社区