原創做者,公衆號【程序員讀書】,歡迎關注公衆號,轉載文章請註明出處哦。nginx
在Go語言中開發Web應用,真的是一件很是簡單的事情,由於Go語言標準庫中就有很是成熟且簡單的Web開發包:net/http
。程序員
net/http封裝了開發Web應用所須要的大部分功能,所以,在Go語言中使用net/http開發Web應用程序時,咱們甚至都不用像其餘語言(好比PHP)同樣須要本身再搭一個Apache或nginx等Web服務器,而是隻須要簡單幾行代碼就能夠搭建一個Web服務應用。web
固然,雖然使用Go的net/http包能夠簡單開發Web應用,但咱們在開發中仍然須要牢固地掌握開發Web程序所須要的基礎知識,而Web開發中最基礎和最核心的知識就是:HTTP協議
。編程
http協議是Web服務器與客戶端(最多見就是瀏覽器)之間通信的語言與規範,瀏覽器向Web發起請求到Web服務器響應並結束鏈接,整個過程以下圖所示:瀏覽器
一個完整http事務,由一個客戶端的請求和Web服務器響應構成,客戶端發起的請求,包括三個部分:請求行
、請求頭
和請求體
,而Web服務器的響應一樣包含三部分:響應行
、響應頭
和響應體
,以下圖所示:。bash
http協議的相關知識遠不僅這些,咱們有空再談談。服務器
使用HandleFunc函數是http封裝好的一個函數,能夠直接使用,第一個參數是web請求路徑,第二個參數是的func(writer http.ResponseWriter, request *http.Request)
函數。函數
再使用http.ListenAndServe(":8080",nil)
語句,監聽8080
端口,運行程序後。學習
使用http://localhost:8080,便會輸出一塊兒學習Go Web編程吧
。ui
其中http.ResponseWriter
表明對客戶端的響應體,而http.Request
表明客戶端發送服務器的請求數據。
func hello(writer http.ResponseWriter, request *http.Request) {
writer.Write([]byte("一塊兒學習Go Web編程吧"));
}
func main(){
http.HandleFunc("/hello",hello)
log.Fatal(http.ListenAndServe(":8080",nil))
}
複製代碼
跟HandleFunc
同樣,Handle
也是http封裝好的函數,第一個參數跟HandleFunc
同樣,而第二個參數則是必須是實現了http.Handler
接口的類型,http.Handler
在http包的定義以下:
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
複製代碼
下面咱們定義一個Controller結構體,在該結構定義ServeHTTP方法,所以Controller結構也實現http.Handler接口,而經過http.HandlerFunc
也能將hello方法轉成一個實現http.HandlerFunc
,http.HandlerFunc
也實現http.Handler
,http.HandlerFunc
在http包的定義以下:
type HandlerFunc func(ResponseWriter, *Request)
// ServeHTTP calls f(w, r).
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
f(w, r)
}
複製代碼
其實,在上面的例子中,咱們將hello傳給http.HandleFunc
函數時,HandleFunc
函數也是使用http.HandlerFunc
將hello轉換成http.HandlerFunc
的。
下面有關http.Handle的示例:
type Controller struct {}
func (c Controller)ServeHTTP(writer http.ResponseWriter, request *http.Request){
writer.Write([]byte("hello,1"));
}
func hello(writer http.ResponseWriter, request *http.Request) {
writer.Write([]byte("hello,2"));
}
func main(){
http.Handle("/hello1",&Controller{})
http.Handle("/hello2",http.HandlerFunc(hello))
log.Fatal(http.ListenAndServe(":8080",nil))
}
複製代碼
運行程序後,在瀏覽器輸入下面的地址:
http://localhost:8080/hell1, 輸出:hello,1
http://localhost:8080/hell2, 輸出:hello,2
不管是使用http.Handle
仍是http.HandleFunc
函數,其實底層代碼都是使用http.DefaultServeMux
,DefaultServeMux
的定義以下代碼所示:
var DefaultServeMux = &defaultServeMux
var defaultServeMux ServeMux
複製代碼
type Controller struct {}
func (c Controller)ServeHTTP(writer http.ResponseWriter, request *http.Request){
writer.Write([]byte("hello,1"));
}
func hello(writer http.ResponseWriter, request *http.Request) {
writer.Write([]byte("hello,2"));
}
func main(){
mux := &http.ServeMux{}
mux.HandleFunc("/hello1",hello)
mux.Handle("/hello2",http.HandlerFunc(hello))
mux.Handle("/hello3",&Controller{})
log.Fatal(http.ListenAndServe(":8080",mux))
}
複製代碼
運行程序後,在瀏覽器輸入下面的地址:
http://localhost:8080/hell1, 輸出:hello,1
http://localhost:8080/hell2, 輸出:hello,1
http://localhost:8080/hell3, 輸出:hello,2
http.Server
是http包中對web更加底層的支持,咱們前面使用的方法,都是對http.Server
的封裝而已,若是直接使用http.Server
,則能夠自定義更多的參數,若是鏈接超時等參數,所以咱們下面直接使用http.Server
開發Web服務。
func main() {
myHandler := &http.ServeMux{}
myHandler.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("hello"))
})
s := &http.Server{
Addr: ":8080",
Handler: myHandler,
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
MaxHeaderBytes: 1 << 20,
}
log.Fatal(s.ListenAndServe())
}
複製代碼
運行程序後,在瀏覽器輸入下面的地址:
http://localhost:8080/hello, 輸出:hello
經過上面的例子,能夠看出Go Web開發可很簡單,可是實際中,一個真正Web應用所要作的事,遠不僅這麼簡單,對於Go Web開發,仍是有不少東西要學的。
你的關注,是我寫做路上最大的鼓勵!