Go Web编程 第三章--接收请求
net/http标准库
net/http标准库通常包括两个部分,客户端和服务器,我们可以通过ListenAndServe创建一个简陋的服务器
package main
import (
"net/http"
)
func main() {
http.ListenAndServe("", nil)
}
这会使用默认的80端口进行网络连接,并且使用默认的多路复用器DefaultServeMux,我们也可以通过Server结构进行更详细的配置
func main() {
server := http.Server {
Addr: "127.0.0.1:80",
Handler: nil,
}
server.ListenAndServe()
}
处理器和处理函数
处理器
前面的代码会返回404响应,因为我们还没有为请求编写相应的处理器。一个处理器就是一个拥有ServeHTTPf方法的接口
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
我们通过实现这个接口来编写处理器
type MyHandler struct{}
func (h *MyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, world")
}
func main() {
handler := MyHandler{}
server := http.Server {
Addr: "127.0.0.1:80",
Handler: &handler,
}
server.ListenAndServe()
}
我们可以设置多个处理器
type HelloHandler struct{}
func (hello *HelloHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "hello!")
}
type WorldHandler struct{}
func (world *WorldHandler) ServeHTTP(w http.ResponseWriter, r *http.Reuest) {
fmt.Fprintf(w, "world!")
}
func main() {
hello := HelloHandler{}
world := WorldHandler{}
server := http.Server {
Addr: "127.0.0.1:80",
}
http.Handle("/hello", &hello)
http.Handle("/world", &world)
server.ListenAndServe()
}
我们看一下Handle函数再源码中的定义
func Handle(pattern string, handler Handler) {
DefaultServeMux.Handle(pattern, handler)
}
实际上是在调用DefaultServeMux的某个方法,前面我们已经提到过了DefaultServeMux是个默认多路复用器,实际上它也是个Handler处理器,因为他是ServeMux结构的一个实例,而ServeMux也实现了Handler接口的ServeHTTP方法。这样就可以对不同的请求做出不同的响应。
处理器函数
处理器函数是与处理器拥有同样行为的函数,它们与ServeHTTP拥有同样的函数签名。
func hello (w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello!")
}
func main() {
server := http.Server {
Addr: "127.0.0.1:8080",
}
http.HandleFunc("/hello", hello)
server.ListenAndServe()
}
HandleFunc是Go语言拥有的一种函数类型,它可以把一个带有正确签名的f转换为带有方法f的handler。
来看看HandleFunc的源码
func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
DefaultServeMux.HandleFunc(pattern, handler)
}
func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
if handler == nil {
panic("http: nil handler")
}
mux.Handle(pattern, HandlerFunc(handler))
}
Handle函数是不是似曾相识!
串联多个处理器和处理器函数
func hello(w *http.ResponseWriter, r *Request) {
fmt.Fprintf(w, "Hello!")
}
func log(h http.Handler) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
fmt.Println("Log!")
h(w, r)
}
}
func main() {
server := http.Server {
Addr: "127.0.0.1:8080",
}
http.HandleFunc("/hello", log(hello))
server.ListenAndServe()
}
其中HandlerFunc是实现了Handler接口的函数类型,源码定义:
type HandlerFunc func(ResponseWriter, *Request)
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
f(w, r)
}
ServeMux
ServeMux是一个HTTP请求多路复用器,负责接收HTTP请求并根据请求中的URL将请求重定向到正确的处理器。ServeMux包含一个映射,这个映射会将URL映射至相应的处理器。值得一提的是,ServeMux无法使用变量实现URL模式匹配,因此必要时我们完全可以用其它自建的多路复用器来代替ServeMux,如HttpRouter等高效轻量的第三方复用器