实现handler接口,用来处理请求。
type Handler interface {
ServerHTTP(w ResponseWriter, r *Request)
}
例如,显示一个电子商务网站的库存:
type dollars float32
func (d dollars) String() string {
return fmt.Sprintf("$%.2f", d)
}
type database map[string]dollars //这里用map来表示库存
func (db database) ServeHTTP(w http.ResponseWriter, r *http.Request) {
for item, price := range db {
fmt.Fprintf(w, "%s: %s\n", item, price)
}
fmt.Println(w)
}
主函数,ListenAndServe函数需要一个服务器地址,以及一个Handler接口的实例:
db := database{"shoes": 50, "socks": 5.5}
log.Fatal(http.ListenAndServe("localhost:8000", db))
处理不同的路径时:
func (db database) ServeHTTP(w http.ResponseWriter, r *http.Request) {
switch r.URL.Path {
case "/price":
item := r.URL.Query().Get("item")
price, ok := db[item]
if !ok {
w.WriteHeader(http.StatusNotFound)
fmt.Fprintf(w, "no such item: %q\n", item)
return
}
fmt.Fprintf(w, "price:%s\n", price)
case "/list":
fmt.Fprintf(w, "物品如下:\n")
for item, _ := range db {
fmt.Fprintf(w, "%s\n", item)
}
}
}
go语言net/http包提供了一个全局的ServerMux实例DefaultServeMux,以及包级别的注册程序http.Handle和http.Handlefunc。要让DefaultServeMux作为服务器的主处理程序,无须把它传给ListenAndServe,直接传nil即可。
对于部分程序来说,一个Web服务器足够用,所以用包默认提供的DefaultServeMux。
注册处理程序:
//list必须要和接口的ServerHTTP()方法有一样的签名
func (db database) list(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "物品如下:\n")
for item, _ := range db {
fmt.Fprintf(w, "%s\n", item)
}
}
主函数:
db := database{"shoes": 50, "socks": 5.5}
http.HandleFunc("/list", db.list) //db.list必须要和接口的ServerHTTP()方法有一样的签名
log.Fatal(http.ListenAndServe("localhost:8000", nil))
http.HandleFunc函数实质上是把db.list方法进行了类型转换,利用HandlerFunc类型(名字不一样噢)
type HandlerFunc func(ResponseWriter, *Request)
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
f(w, r)
}
当然也可以自己创建一个ServerMux:
mux := http.NewServeMux()