前言
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) error
type 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_filter
import (
"net/http"
"strings"
)
type FilterHandle func(rw http.ResponseWriter,r *http.Request) error
//攔截uri對映處理
var filterMapping = make(map[string]FilterHandle,0)
//保證有序uri
var 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) error
func 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 test
import (
"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