日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Go语言Web框架gwk介绍 (一)

發布時間:2025/3/8 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Go语言Web框架gwk介绍 (一) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

今天看到Golang排名到前30名了,看來關注的人越來越多了,接下來幾天詳細介紹Golang一個web開發框架GWK。

現在博客園支持markdown格式發布文章么?后臺的編輯器不太好用嘛。

?

GWK

簡介

gwk(GO Web Server Kit)是GO語言的Web Server開發框架,簡單易用,擴展性好,而且兼容Go App Engine。

安裝

gwk只支持GO 1.1+版本,安裝GO 1.1后,運行下面的命令即可。

go get github.com/sdming/wk

gwk依賴kiss和mcache兩個package,如果沒有自動安裝成功的話,可以單獨運行下面的命令安裝:

go get github.com/sdming/kiss go get github.com/sdming/mcache

示例

gwk的文檔比較簡單,寫的不是很詳細,自帶的demo寫的比較全,主要的功能點都涉及到了。

另外Google App Engine上有一個展示gwk demo的網站,是用gwk框架搭建的,也是一個了解gwk的地方。網址是[http://gwk-demo.appspot.com]。?需要注意的是,這個demo網站的示例數據是放在內存的,多用戶訪問時會互相影響 。另外App Engine會自動管理服務實例以及會根據訪問情況自動關閉或啟動服務,示例數據也會受到影響。

啟動服務

gwk不像revel那樣是一個Web Server框架,需要自己寫代碼來啟動gwk的服務。最簡單的方式如下。

server, err := wk.NewDefaultServer()if err != nil {fmt.Println("NewDefaultServer error", err)return }server.RouteTable.Get("/data/top/{count}").To(...)server.Start()

基本步驟就是:

  • 創建HttpServer示例
  • 注冊路由
  • 調用Start方法監聽Http端口

接下來詳細介紹gwk各個功能模塊的用法,先從路由開始。

路由

gwk用RouteTable來存儲注冊的路由,RouteTable的定義如下:

type RouteTable struct {Routes []*RouteRule }

當gwk接收到http請求時,按照順序遍歷RouteRule直到找到匹配的Route,如果沒有找到則返回404。

RouteRule的定義如下:

type RouteRule struct {// Methos is http method of requestMethod string// Pattern is path patternPattern string// Handler process requestHandler Handler }

Method是Http method,比如:GET, POST, PUT, DELETE,*代表匹配所有的http method。
Pattern是URL匹配的模式,具體的格式下面再講。
Handler是用來處理請求的代碼,是一個接口,定義如下:

type Handler interface {Execute(ctx *HttpContext) }

gwk提供了若干方法來注冊路由。一個最簡單的方法是路由到一個func (*wk.HttpContext) (wk.HttpResult, error) 類型的函數,比如:

// url: /data/top/10 server.RouteTable.Get("/data/top/{count}").To(DataTopHandle)

上面的代碼將GET /data/top/10這樣的request path注冊到一個func (*wk.HttpContext) (wk.HttpResult, error)類型的函數,例子中DataTopHandle的定義如下:

func DataTopHandle(ctx *wk.HttpContext) (result wk.HttpResult, err error) {if count, ok := ctx.RouteData.Int("count"); !ok {err = errors.New("parameter invalid:" + "count")} else {data := DataTop(count)result = wk.Json(data)}return }

例子中HttpContext是這次http請求的一個封裝,HttpResult是這次請求返回的數據,詳細的定義在下面會介紹。

通過RouteData可以獲得在request path中匹配到的參數,比如上面的{count}參數,RouteData的定義如下:

type RouteData map[string]string

RouteData提供了若干方法來簡化Route參數的讀取。

讀取整數

func (r RouteData) Int(name string) (int, bool)

讀取整數,如果參數不存在或者不是有效的整數格式則返回一個缺省值

func (r RouteData) IntOr(name string, v int) int

類似的方法還有

Bool,BoolOr,Float,FloatOr,Str,StrOr

asp.net mvc 的開發人員應該會對"/data/top/{count}"這樣的路由規則寫法比較熟悉,gwk支持兩種路由規則的寫法。

  • 正則表達式

    ^/user/?(?P<action>[[:alnum:]]+)?/?(?P<arg>[[:alnum:]]+)?/?

    匹配類似/user/view/1這樣的request path

  • 正則表達式寫起來比較麻煩,而且執行速度慢,你也可以用類似asp.net mvc的寫法,比如

    "/data/top/{count}" "/query/{year}-{month}-{day}" "/basic#/{action}/{id}" "/data/int/{p0}?" "/data/range/{p0}-{p1}"

    規則很簡單,前綴匹配requets path,{}匹配的內容會被提取為參數。其中兩個特殊字符需要介紹一下。

    • "#"字符代表精確匹配#之前的內容,#之后的為可選匹配,比如/basic和/basic/add,/basic/delete/1都匹配上面規則。
    • "?"字符代表匹配request path的結束,比如/data/int/1匹配上面的規則,/data/int/1/foo就不符合上面的規則。

gwk還提供了其他的方式來注冊路由。

通過ToFunc方法注冊路由到一個普通函數,比如

// url: /data/int/1 server.RouteTable.Get("/data/int/{p0}?").ToFunc(model.DataByInt)func DataByInt(i int) *Data {if i < 0 {i = 0}return newData(i) }

再比如

// url: /data/range/1-9 server.RouteTable.Get("/data/range/{p0}-{p1}").ToFunc(model.DataByIntRange)func DataByIntRange(start, end int) []*Data {data := make([]*Data, 2)data[0] = newData(start)data[1] = newData(end)return data }

因為GO的反射不能獲得函數參數的名字,所以這里用p0,p1,p2...來代表函數的第0,1,2...個參數。

gwk會根據http請求中accept的內容來自動決定返回數據的格式,上面的例子中Data定義如下:

type Data struct {Str stringUint uint64Int intFloat float32Byte byte }

如果Request的Accept中包含字符串"xml",則結果序列化為xml格式,如果包含"jsonp",則結果序列化為jsonp,如果包含json,則序列化為json格式,詳細信息可以參考下面的"格式化"一節

除了上面的p0,p1,p2指定參數的方式,可以用BindByNames按照名字來綁定函數的參數,比如:

// url: /data/name/1 server.RouteTable.Get("/data/name/{id}").ToFunc(model.DataByInt).BindByNames("id")

上面的代碼告訴gwk,路由參數"id"是函數DataByInt的第一個參數。

// url: /data/namerange/1-9 server.RouteTable.Get("/data/namerange/{start}-{end}").ToFunc(model.DataByIntRange).BindByNames("start", "end")

上面的代碼告訴gwk,路由參數"start","end"是函數DataByIntRange的第一個和第二個參數。

也可以綁定到querypath或者form中的參數,比如:

// url: /data/namerange/?start=1&end=9 server.RouteTable.Get("/data/namerange/").ToFunc(model.DataByIntRange).BindByNames("start", "end")

再比如:

// url: get /data/set?str=string&uint=1024&int=32&float=3.14&byte=64 server.RouteTable.Get("/data/set?").ToFunc(model.DataSet).BindByNames("str", "uint", "int", "float", "byte")func DataSet(s string, u uint64, i int, f float32, b byte) *Data {return &Data{Str: s,Uint: u,Int: i,Float: f,Byte: b,} }

如果參數比較多,一個合適的方法是將參數定義為一個struct,然后調用BindToStruct來綁定參數。比如:

// url: post /data/post? // form:{"str": {"string"}, "uint": {"1024"}, "int": {"32"}, "float": {"1.1"}, "byte": {"64"}} server.RouteTable.Post("/data/post?").ToFunc(model.DataPost).BindToStruct()func DataPost(data Data) string {return data.String() }// url: post /data/postptr? // form:{"str": {"string"}, "uint": {"1024"}, "int": {"32"}, "float": {"1.1"}, "byte": {"64"}} server.RouteTable.Post("/data/postptr?").ToFunc(model.DataPostPtr).BindToStruct()func DataPostPtr(data *Data) string {return data.String() }

如果覺得每個函數定義一個參數對象比較麻煩,也可以用匿名對象:

server.RouteTable.Get("/data/anonymous?").ToFunc(DataAnonymous).BindToStruct()func DataAnonymous(data struct {Str stringUint uint64Int intFloat float32Byte byte },) string {return fmt.Sprintln(data) }

更方便的路由方式是注冊一個到controller的路由,在controller一節會介紹。

格式化

gwk會根據http請求中accept的內容來自動決定返回數據的格式,如果Request的Accept中包含字符串"xml",則結果序列化為xml格式,如果包含"jsonp",則結果序列化為jsonp,如果包含json,則序列化為json格式。具體的例子可以看http://gwk-demo.appspot.com/doc/routedemo

你也可以通過設置Formatter來指定輸出的格式,Formatter的定義如下

type FormatFunc func(*HttpContext, interface{}) (HttpResult, bool)

gwk默認支持兩種序列化方式,xml和json。比如:

// url: /data/int/1/xml server.RouteTable.Get("/data/int/{p0}/xml").ToFunc(model.DataByInt).ReturnXml()// url: /data/int/1/json server.RouteTable.Get("/data/int/{p0}/json").ToFunc(model.DataByInt).ReturnJson()

ReturnXml指定DataByInt的返回值格式化為xml,ReturnJson指定DataByInt的返回值格式化為json。

你也可以自定義序列化的方式,比如:

// url: /data/int/1/kson server.RouteTable.Get("/data/int/{p0}/kson").ToFunc(model.DataByInt).Return(formatKson)func formatKson(ctx *wk.HttpContext, x interface{}) (wk.HttpResult, bool) {b, _ := kson.Marshal(x)return wk.Content(string(b), "text/plain"), true }

kson格式是gwk的配置文件采用的格式,后文會詳細介紹,上面的代碼返回的數據如下:

{Str:string:1Uint:100Int:10Float:1.1Byte:1 }

gwk還提供了注冊全局FormatFunc的地方:

type FormatList []FormatFunc var Formatters FormatList

你可以通過增刪Formatters或者修改Formatters的順序來調整默認的格式化方式。

Controller

當需要注冊的路由方法比較多,而且之間有一定的邏輯關系時,可以定義一個類似的asp.net mvc的Controller對象,然后將路由指向這個對象。代碼可以參考https://github.com/sdming/wk/blob/master/demo/basic/controller/basic.go

一個簡單的注冊Controller的例子如下:

basic = NewBasicController()// url: /basic/xxx/xxx server.RouteTable.Path("/basic#/{action}/{id}").ToController(basic)

用正則表達式的話,例子如下

srv.RouteTable.Regexp("*", "^/user/?(?P<action>[[:alnum:]]+)?/?(?P<arg>[[:alnum:]]+)?/?").ToController(NewUserController())

注冊到controller的路由,一個特殊的路由參數是{action},它指定了調用Controller的哪一個方法。比如/basic/delete/32對應的action是"delete",調用controller的delete方法,一個例子如下:

// url: /basic/delete/32 func (c *BasicController) Delete(ctx *wk.HttpContext) (result wk.HttpResult, err error) {l := len(c.data)if i, ok := ctx.RouteData.Int("id"); ok {c.deleteByInt(i)}return wk.Data(l - len(c.data)), nil }

gwk現在版本的controller只支持func (ctx *wk.HttpContext) (result wk.HttpResult, err error)類型的方法,已經基本夠用了。

再看一個例子:

// url: /basic/add/?int=32&str=string&uint=1024&float=1.1&byte=64 func (c *BasicController) Add(ctx *wk.HttpContext) (result wk.HttpResult, err error) {data := &model.Data{Int: ctx.FormIntOr("int", 0),Uint: uint64(ctx.FormIntOr("uint", 0)),Str: ctx.FormValue("str"),Float: float32(ctx.FormFloatOr("float", 0.0)),Byte: byte(ctx.FormIntOr("byte", 0)),}c.data = append(c.data, data)return wk.Data(data.String()), nil }

FormIntOr,FormFloatOr等函數是為了方便讀取Request Form數據,可以參考RouteData的對應函數。

wk.Data函數返回 *DataResult對象,*DataResult實現了wk.HttpResult接口, HttpResult接口的詳細介紹見后面的章節。

func Data(data interface{}) *DataResult {return &DataResult{Data: data,} }

再看一個返回json數據的例子

// url: /basic/int/32 func (c *BasicController) Int(ctx *wk.HttpContext) (result wk.HttpResult, err error) {if id, ok := ctx.RouteData.Int("id"); ok {return wk.Json(c.getByInt(id)), nil}return wk.Data(""), nil }

再看一個直接讀取post的數據,解析成json的例子:

// url: post /basic/post func (c *BasicController) Post(ctx *wk.HttpContext) (result wk.HttpResult, err error) {var body []byteif body, err = ctx.ReadBody(); err != nil {return nil, err}data := &model.Data{}err = json.Unmarshal(body, data)if err != nil {return nil, err}c.data = append(c.data, data)return wk.Data(true), nil }

如果沒有找到路由參數{action},gwk會將http method作為action,也就是把"get","post","delete"作為action,如果找不到對應的方法,會將{action}{method}組合起來作為action,這在一些場合還是比較實用的,如果還找不到對應的方法,則將"default"作為action,如果還是找不到對應的方法,則返回404.

各種流行的MVC類開發框架比較多,controller應該不用做過多的介紹,接下來介紹HttpResult接口。

轉載于:https://www.cnblogs.com/buzzlight/p/gwk_basic_01.html

總結

以上是生活随笔為你收集整理的Go语言Web框架gwk介绍 (一)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。