golang的net/http包中的http.Handle本身就是支持面向对象,但是由于包的实现最终需要调用http.ServeHTTP方法实现,所以一般都是直接调用http.HandleFunc来进行路由注册,这里我基于http.Handle方法来进行面向对象的封装,代码如下:
import (
"net/http"
)
type Getter interface {
Get(http.ResponseWriter, *http.Request)
}
type Poster interface {
Post(http.ResponseWriter, *http.Request)
}
type Putter interface {
Put(http.ResponseWriter, *http.Request)
}
type Deleter interface {
Delete(http.ResponseWriter, *http.Request)
}
type PackedHandler struct {
getter Getter
poster Poster
putter Putter
deleter Deleter
}
func (h *PackedHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if len(r.Header["localCheckResult"]) == 1 {
w.Write([]byte(r.Header["localCheckResult"][0]))
return
}
if r.Method == "GET" && h.getter != nil {
h.getter.Get(w, r)
} else if r.Method == "POST" && h.poster != nil{
h.poster.Post(w, r)
} else if r.Method == "PUT" && h.putter != nil{
h.putter.Put(w,r)
} else if r.Method == "DELETE" && h.deleter != nil {
h.deleter.Delete(w,r)
} else {
w.Write([]byte("404 not found"))
}
}
//业务handler封装,统一添加ServeHTTP方法
func PackHandler(businessHandler interface{}) *PackedHandler{
packedHandler := new(PackedHandler)
packedHandler.getter, _ = businessHandler.(Getter)
packedHandler.poster, _ = businessHandler.(Poster)
packedHandler.putter, _ = businessHandler.(Putter)
packedHandler.deleter, _ = businessHandler.(Deleter)
return packedHandler
}
简单说明上述代码:业务struct只负责实现具体的方法,最后调用的时候用PackHandler接口封装,添加ServeHTTP方法,并在方法内部进行request method的判断调用相应的实现方法。
最后路由注册实现(嵌套了中间件):
http.Handle("/record", middleware.MidHandler(PackHandler(&controllers.RecordHandler{}), middleware.CheckSignature))
去掉中间件就是这样:
http.Handle("/record", PackHandler(&controllers.RecordHandler{}))
其中controllers.RecordHandler为业务逻辑结构体。