本篇内容介绍了“Golang net/http知识的详细介绍”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
以下是对net/http的学习。
Go 语言中处理 HTTP 请求主要跟两个东西相关:ServeMux 和 Handler。 ServrMux 本质上是一个 HTTP 请求路由器(或者叫多路复用器,Multiplexor)。它把收到的请求与一组预先定义的 URL 路径列表做对比,然后在匹配到路径的时候调用关联的处理器(Handler)。
处理器(Handler)负责输出HTTP响应的头和正文。任何满足了http.Handler接口的对象都可作为一个处理器。通俗的说,对象只要有个如下签名的ServeHTTP方法即可:
ServeHTTP(http.ResponseWriter, *http.Request)
Go 语言的 HTTP 包自带了几个函数用作常用处理器,比如FileServer,NotFoundHandler 和 RedirectHandler。我们从一个简单具体的例子开始:
package main import ( "log" "net/http" ) func main() { mux := http.NewServeMux() rh := http.RedirectHandler("http://www.baidu.com", 307) mux.Handle("/foo", rh) log.Println("Listening...") http.ListenAndServe(":3000", mux) }
快速地过一下代码:
在 main 函数中我们只用了 http.NewServeMux 函数来创建一个空的 ServeMux。 然后我们使用 http.RedirectHandler 函数创建了一个新的处理器,这个处理器会对收到的所有请求,都执行307重定向操作到 http://www.baidu.com。 接下来我们使用 ServeMux.Handle 函数将处理器注册到新创建的 ServeMux,所以它在 URL 路径/foo 上收到所有的请求都交给这个处理器。 最后我们创建了一个新的服务器,并通过 http.ListenAndServe 函数监听所有进入的请求,通过传递刚才创建的 ServeMux来为请求去匹配对应处理器。
然后在浏览器中访问 http://localhost:3000/foo 你应该能发现请求已经成功的重定向了。
明察秋毫的你应该能注意到一些有意思的事情:ListenAndServer 的函数签名是 ListenAndServe(addr string, handler Handler) ,但是第二个参数我们传递的是个 ServeMux。
我们之所以能这么做,是因为 ServeMux 也有 ServeHTTP 方法,因此它也是个合法的 Handler。
对我来说,将 ServerMux 用作一个特殊的Handler是一种简化。它不是自己输出响应而是将请求传递给注册到它的其他 Handler。这乍一听起来不是什么明显的飞跃 - 但在 Go 中将 Handler 链在一起是非常普遍的用法。
真正的重点是我们有一个对象(本例中就是个timerHandler结构体,但是也可以是一个字符串、一个函数或者任意的东西),我们在这个对象上实现了一个 ServeHTTP(http.ResponseWriter, *http.Request) 签名的方法,这就是我们创建一个处理器所需的全部东西。
package main import ( "log" "net/http" "time" ) type timeHandler struct { format string } func (th *timeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { tm := time.Now().Format(th.format) w.Write([]byte("The time is : " + tm)) } func main() { mux := http.NewServeMux() rh := http.RedirectHandler("http://www.baidu.com", 307) th := &timeHandler{format: time.RFC1123} mux.Handle("/a", rh) mux.Handle("/time", th) log.Println("Listening.....") http.ListenAndServe(":3000", mux) }
http.HandlerFunc()能够让一个常规函数作为一个Handler接口条件
func timeHandler(w http.ResponseWriter, r *http.Request) { tm := time.Now().Format(time.RFC1123) w.Write([]byte("the time is : " + tm)) } func main() { mux := http.NewServeMux() rh := http.RedirectHandler("http://www.baidu.com", 307) th := http.HandlerFunc(timeHandler) mux.Handle("/a", rh) mux.Handle("/time", th) log.Println("Listening.....") http.ListenAndServe(":3000", mux) }
更为便捷的方式:ServerMux.HandlerFunc 方法
func main() { mux := http.NewServeMux() mux.HandleFunc("/time", timeHandler) log.Println("Listening...") http.ListenAndServe(":3000", mux) }
如果方法中需要参数,则需要使用闭包,将变量带入:
//demo1 func timeHandler(format string) http.Handler{ fn:=func(w http.ResponseWriter,r *http.Request){ tm:=time.Now().Format(format) w.Write([]byte("The time is : "+tm)) } return http.HandlerFunc(fn) } //demo2 func timeHandler(format string) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { tm := time.Now().Format(format) w.Write([]byte("The time is: " + tm)) }) } //demo3 func timeHandler(format string) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { tm := time.Now().Format(format) w.Write([]byte("The time is: " + tm)) } }
net/http 包提供了一组快捷方式来配合 DefaultServeMux:http.Handle 和 http.HandleFunc。这些函数与我们之前看过的类似的名称的函数功能一样,唯一的不同是他们将处理器注册到 DefaultServerMux ,而之前我们是注册到自己创建的 ServeMux。
此外,ListenAndServe在没有提供其他的处理器的情况下(也就是第二个参数设成了 nil),内部会使用 DefaultServeMux。
因此,作为最后一个步骤,我们使用 DefaultServeMux 来改写我们的 timeHandler应用:
func timeHandler(format string) http.Handler { fn := func(w http.ResponseWriter, r *http.Request) { tm := time.Now().Format(format) w.Write([]byte("The time is : " + tm)) } return http.HandlerFunc(fn) } func main() { /* mux := http.NewServeMux() rh := http.RedirectHandler("http://www.baidu.com", 307) th := timeHandler(time.RFC1123) mux.Handle("/a", rh) mux.Handle("/time", th) log.Println("Listening.....") http.ListenAndServe(":3000", mux) */ var format string = time.RFC1123 th := timeHandler(format) http.Handle("/time", th) log.Println("listening....") http.ListenAndServe(":3000", nil) }
“Golang net/http知识的详细介绍”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。