Go语言学习--接受和处理Web请求之接收请求(更新中......)
Go Web服务器请求和响应的流程如下:
1.客户端发送请求
2.服务器端的多路复用器收到请求
3.多路复用器根据请求的URL找到注册的处理器,将请求交由处理器处理
4.处理器执行程序逻辑,如有必要,则与数据库进行交互,得到处理结果
5.处理器调用模版引擎将指定的模版和上一步得到的结果渲染成客户端可识别的数据格式
6.服务器端将数据通过HTTP响应返回给客户端
7.客户端拿到数据,执行对应的操作
接收请求
ServerMux与DefaultServeMux
多路复用器的原理:用于转发请求到处理器
ServeMux是一个结构体,其中包含一个映射,这个映射会将URL映射到响应的处理器。它会在映射中找出与被请求的URL最为匹配的URL,然后调用与之相应的处理器的ServeHTTP()
方法来处理请求。
DefaultServeMux是ServeMux的一个实例。多路复用器的任务是-根据请求的URL将请求定向到不同的处理器。如果用户没有为Server对象指定处理器,则服务器默认使用DefaultServeMux。
在Go语言中,对于Web离不开两个函数:HandleFunc()和ListenAndServe()
HandleFunc()函数用于为指定的URL注册一个处理器。HandleFunc()处理器函数会在内部调用DefaultServeMux对象的对应方法。
源码如下:
func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
DefaultServeMux.HandleFunc(pattern, handler)
}
http.HandleFunc()函数将处理器注册到多路复用器中。来看下官方解释:
// HandleFunc registers the handler function for the given pattern
// in the DefaultServeMux.
// The documentation for ServeMux explains how patterns are matched.
来看一下用默认多路复用器指定多个处理器的案例:
package main import ( "fmt" "net/http" ) type handle1 struct { } func (h1 *handle1) ServeHTTP(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "hi,handle1") } type handle2 struct { } func (h2 *handle2) ServeHTTP(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "hi,handle2") } //func Handle(pattern string, handler http.Handler) { // http.DefaultServeMux.Handle(pattern, handler) //} func main() { handle1 := handle1{} handle2 := handle2{} server := http.Server{ Addr: "0.0.0.0:8085", Handler: nil, } http.Handle("/handle1", &handle1) http.Handle("/handle2", &handle2) server.ListenAndServe() }
运行结果:
但是默认的多路复用器不建议在生产环境下使用,因为DefaultServeMux是一个全局变量,所有代码都可以修改它。所有引入接下来的自定义多路复用器。
自定义多路复用器:直接调用http.NewServeMux()函数即可。然后,新创建的多路复用器上注册处理器。
来看一下案例:
package main import ( "fmt" "log" "net/http" ) func hi(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "hi,Go Web") } func main() { mux := http.NewServeMux() mux.HandleFunc("/", hi) server := &http.Server{ Addr: ":8081", Handler: mux, } if err := server.ListenAndServe(); err != nil { log.Fatal(err) } }
运行结果:
(更新中。。。。。)