square-gopher.png

Http 请求是一种无状态的通讯模型,无状态可能对于初学者听起来有点 confusing。这里的无状态表明每一次请求都是独立相互之间没有关系。每一次请求不会受到上一次请求的影响。
在 net/http 模块中提供两个组件来处理 Http 请求。


golang_real.jpg

ServeMux

ServeMux 是一个多路复用器(或简单的HTTP请求路由器),根据 HTTP 的请求来在
预定义的 URI 资源列表中查找来相应的资源返回给客户端。

我们在项目目录下创建一个 public 文件夹,文件夹中我们可以先简单地创建一个 about.html


屏幕快照 2019-04-20 上午6.43.31.png

创建一个静态的服务

package main

import(
    "net/http"
)

func main()  {
    mux := http.NewServeMux()
    fs := http.FileServer(http.Dir("public"))
    mux.Handle("/", fs)
    http.ListenAndServe(":8080", mux)
}
http.NewServeMuxmux.Handle("/", fs)/
ListenAndServeListenAndServe
[http://localhost:8080/about.html](http://localhost:8080/about.html)

自定义处理器

当然可以根据自己需要对每个路由进行不同处理,现在我们就通过示例来给大家演示如何自定义对路由进行处理的处理器。
首先我们来定义一个消息的结构体,我们需要根据用户输入不同的路由来反馈不同的内容。

type messageHandler struct{
    message string
}

bjtgdcrlkusasdsravci.jpg
ServeHTTP(w http.ResponseWriter, r *http.Request)
func (m *messageHandler) ServeHTTP(w http.ResponseWriter, r *http.Request){
    fmt.Fprintf(w, m.message)
}
fmt.Fprintf(w, m.message)

完整代码如下

package main

import(
    "net/http"
    "fmt"
    "log"
)
type messageHandler struct{
    message string
}

func (m *messageHandler) ServeHTTP(w http.ResponseWriter, r *http.Request){
    fmt.Fprintf(w, m.message)
}

func main()  {
    mux := http.NewServeMux()

    welcomeHandler := &messageHandler{
        "welcome to zidea",
    }

    mux.Handle("/welcome",welcomeHandler)

    angularTutHandler := &messageHandler{
        "angular basic tut",
    }

    mux.Handle("/angular",angularTutHandler)

    log.Println("Listening...")
    http.ListenAndServe(":8080",mux)
}
屏幕快照 2019-04-20 上午6.43.22.png

函数处理器

HandlerFunc
func welcomeHandlerFunc(w http.ResponseWriter, r *http.Request){
    fmt.Fprintf(w, "welcome to zidea")
}

func main()  {
    mux := http.NewServeMux()

    welcomeHandler := http.HandlerFunc(welcomeHandlerFunc)

    mux.Handle("/welcome",welcomeHandler)
    
    log.Println("Listening...")
    http.ListenAndServe(":8080",mux)
}

当函数的参数为(http.responsewriter,http.request)。handlerFunc 可以作为适配器,将这个函数用转换为 HTTP 处理程序。原因是 handlerFunc 类型中有内置方法ServeHTTP(http.responsewriter,http.request),因此就满了 足http.handler 接口,可以作为 HTTP 处理程序工作。

messageHandlerhttp.Handlerhttp.HandlerFunc
func messageHandler(message string) http.Handler{
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request){
        fmt.Fprintf(w, message)
    })
}

func main()  {
    mux := http.NewServeMux()

    mux.Handle("/welcome",messageHandler("welcome to zidea"))
    mux.Handle("/angular",messageHandler("angular basic tut"))
    
    log.Println("Listening...")
    http.ListenAndServe(":8080",mux)
}

自定义服务器

http.ListenAndServe
type Server struct {
 Addr string
 Handler Handler
 ReadTimeout time.Duration
 WriteTimeout time.Duration
 MaxHeaderBytes int
 TLSConfig *tls.Config
 TLSNextProto map[string]func(*Server, *tls.Conn, Handler)
 ConnState func(net.Conn, ConnState)
 ErrorLog *log.Logger
}
import(
    "net/http"
    "fmt"
    "log"
    "time"
)



func messageHandler(w http.ResponseWriter, r *http.Request){
        fmt.Fprintf(w, "welcome to zidea")
}

func main()  {
    http.HandleFunc("/welcome", messageHandler)

    server := &http.Server{
        Addr: ":8080",
        ReadTimeout: 10 * time.Second,
        WriteTimeout: 10 * time.Second,
        MaxHeaderBytes: 1 << 20,
    }

    
    log.Println("Listening...")
    server.ListenAndServe()
}
th-5.jpeg

参考了 Web Development with Go 一书