前言:此框架的請求處理主要是依賴於Golang中的net/http包
-
http.ListenAndServe 方法的使用
-
實現http簡單服務示例:參考文檔 https://studygolang.com/pkgdoc
-
示例1
http.Handle("/foo", fooHandler) http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path)) }) log.Fatal(http.ListenAndServe(":8080", nil)) -
示例2:
s := &http.Server{ Addr: ":8080", Handler: myHandler, ReadTimeout: 10 * time.Second, WriteTimeout: 10 * time.Second, MaxHeaderBytes: 1 << 20, } log.Fatal(s.ListenAndServe())
-
-
-
本框架的處理思路:
-
從http包看,http.ListenAndServe(":8080", nil) 這個方法的第二個參數是http.Handler對象,而這個對象是一個接口,所以要實現ServeHttp方法
type Handler interface { ServeHTTP(ResponseWriter, *Request) } -
在core包下面聲明了一個Application對象,這個對象實現了 ServeHTTP 方法,在這個方法里面進行路由的判斷,然后根據取到的路由找到 控制器和對應的方法,最后在協程里面利用反射調用 對用的控制器的相應的方法從而得到調用方法的結果(這個結果指的是方法調用成功或者失敗之類的結果)。在執行調用方法的過程中,http請求的參數通過 ServeHTTP的 *Request對象獲取,http的響應的結果可以通過 fmt.Fprint(ResponseWriter對象, "響應結果字符串")。
注:關於請求參數的獲取以及響應結果的返回,在之后的博客中會詳細講到。
-
框架入口:public包中的main.go
func main() { routers := route.GetRouter() controllers := route.GetControllers() app := new(core.Application) app.Routers = routers app.Controllers = controllers err := http.ListenAndServe("localhost:8080", app) if err != nil { log.Println("ListenAndServe: ", err) } } }在這個方法中首先 初始化一個Application對象,然后獲取用戶注冊的路由及控制器,將其作為app對象的屬性賦給app對象,然后使用http.ListenAndServe("localhost:8080", app) 。當請求過來的時候就會直接到app的ServeHTTP方法中,然后就會順着 2 的思路執行。
-
-
其他處理
-
路由的處理
在這個框架中路由如下:
package route import "goweb/controller" var routers = map[string]string{ // 示例 請求類型@控制器@方法 "/test": "get@TestController@Test", } var controllers = map[string]interface{}{ // 示例 反射中用到 "TestController": &controller.TestController{}, } func GetRouter() map[string]string { return routers } func GetControllers() map[string]interface{} { return controllers }在1.2.3 中提到了這個框架的路由的使用時 賦值給app對象了,然后再app中進行路由處理。通過routers數組可以獲取路由和控制器、方法之間的關系,通過controllers數組獲取到對應的控制器的結構體的地址,然后通過反射機制調用對應的控制器的對應方法
-
利用反射調用方法
// 反射調用方法 func CallFuncByName(myClass interface{}, funcName string, params ...interface{}) (out []reflect.Value, err error) { myClassValue := reflect.ValueOf(myClass) m := myClassValue.MethodByName(funcName) if !m.IsValid() { return make([]reflect.Value, 0), fmt.Errorf("Method not found \"%s\"", funcName) } in := make([]reflect.Value, len(params)) for i, param := range params { in[i] = reflect.ValueOf(param) } out = m.Call(in) return out, nil }反射一般用在知道對象及方法名稱,想要得到對象的類或者調用對象的方法的情況。在MVC框架中(根據解析到的路由,動態執行方法)用得比較多一些。
-
注:1. 本文涉及到的代碼的git倉庫地址:https://github.com/zhuchenglin/goweb
2. 如需轉載請注明出處: https://www.cnblogs.com/zhuchenglin/p/12687746.html
