前言
golang web 通過http handle模組進行restful介面與請求處理綁定;既然用了restful每個公司或項目都會制定自己的設計原則和約束條件。在日常開發中通常會根據uri匹配規則在請求進入controller之前進行一些特殊處理(許可權、功能驗證...);在Java web編程中 servlet filter協助我們實現了這樣的功能,golang web通過擴充http handle即可實現
案例:
/safe
/safe/user
假定:
以/safe開頭的請求對用戶端請求參數進行解密
以/safe/user開頭的請求不僅要對用戶端請求參數進行解密還要驗證當前請求使用者是否線上
實現思路:
定義FilterHandle、WebHandle類型
type FilterHandle func(rw http.ResponseWriter,r *http.Request) errortype WebHandle func(rw http.ResponseWriter,r *http.Request) error
FilterHandle 攔截器處理函數
WebHandle 用戶端請求處理函數
http handle模組與攔截器處理函數綁定 在攔截器處理函數中通過閉包回調WebHandle
註冊攔截器處理函數
func Register(uriRule string,fh FilterHandle)
uri 路徑匹配規則
★★★★★ 攔截器註冊在http server 啟動前
web filter程式碼範例:
/** * Created with IntelliJ IDEA. * Description: * User: yangzhao * Date: 2018-08-02 * Time: 11:01 */package web_filterimport ( "net/http" "strings")type FilterHandle func(rw http.ResponseWriter,r *http.Request) error//攔截uri映射處理var filterMapping = make(map[string]FilterHandle,0)//保證有序urivar uriArray = make([]string,0)/** uriRule 路徑匹配規則 fh 攔截器處理函數 */func Register(uriRule string,fh FilterHandle) { uriRule = uriRule[:len(uriRule)-2] filterMapping[uriRule]=fh uriArray = append(uriArray,uriRule)}type WebHandle func(rw http.ResponseWriter,r *http.Request) errorfunc Handle(webHandle WebHandle) func(rw http.ResponseWriter,r *http.Request) { return func(rw http.ResponseWriter,r *http.Request){ var uri=r.RequestURI uri+="/" for _,v:=range uriArray{ if strings.Contains(uri,v) { e := filterMapping[v](rw, r) if e != nil { rw.Write([]byte(e.Error())) return } } } err := webHandle(rw, r) if err != nil { rw.Write([]byte(err.Error())) } }}
測試demo
/** * Created with IntelliJ IDEA. * Description: * User: yangzhao * Date: 2018-08-01 * Time: 16:16 */package testimport ( "net/http" "log" "errors" "testing" "common-go/web/filter" "fmt")type HttpServer struct { http.Server }func (server *HttpServer) StartServer() { log.Println("web server start "+server.Addr) err := server.ListenAndServe() if err != nil { log.Panic(err) }}func (server *HttpServer)ServeHTTP(wr http.ResponseWriter, r *http.Request)() { fmt.Println("測試")}func TestWebFilter(t *testing.T) { web_filter.Register("/safe/**", func(rw http.ResponseWriter, r *http.Request)error { return errors.New("解密失敗") //return nil }) web_filter.Register("/safe/user/**", func(rw http.ResponseWriter, r *http.Request)error { return errors.New("請登入") //return nil }) http.HandleFunc("/safe", web_filter.Handle(func(wr http.ResponseWriter,req *http.Request) error{ wr.Write([]byte(req.RequestURI)) return nil })) http.HandleFunc("/safe/user/test", web_filter.Handle(func(wr http.ResponseWriter,req *http.Request) error{ wr.Write([]byte(req.RequestURI)) return nil })) http.HandleFunc("/safe/user", web_filter.Handle(func(wr http.ResponseWriter,req *http.Request) error{ wr.Write([]byte(req.RequestURI)) return nil })) server := &HttpServer{} server.Addr=":8080" server.StartServer()}
以上屬於原創文章,轉載請註明作者@怪咖
QQ:208275451