根據接口規範文檔要求,需要通過POST請求發送參數,但是示例卻是Get形式的
http://xxx.xxx.com?method=queryMember&appKey=appkey&jsonData={}×tamp=2012-01-20 08:50:15&sign=7E65B60DCFA42B043FCF57169867082C。
我得計劃是一個關鍵點,一個關鍵點的實現,最後實現功能要求。
第一關鍵點,服務端能接收到請求發送的參數。首先,通過bee new 命令,新建一個web項目。然後在 controllers包內,新建POST方法,通過appKey := c.GetString(“appKey”)來獲取參數的值,beego.info(appKey)將變量值打印出來,驗證數據是否正確。
相關視頻教程:兄弟連區塊鏈教程2:Beego詳解 04.簡單路由 和Go語言Web開發Beego框架深入淺出第6節get請求和post請求的處理。
服務端的go代碼寫好,通過postman來發送請求驗證一下,但是沒有獲得預想的數據。因爲不清楚原因,4月4號、5號兩天時間來查找原因,將beego的controller的封裝瞭解了,官方的Http標準庫文檔看了一遍,還有《GO Web 編程》的第三章,重點理解請求、相應的概念,Http裏post和get發送請求的區別等。理論知識有了,問題還是找不到原因。決定拋開beego,按照3.2的示例,用liteide新建最簡單的項目,做了最簡單web服務,依然獲取不到數據。這樣才懷疑是否postman發送請求有問題,通過瀏覽器複製進示例網址,服務端能正常接收參數,確認是post有問題,受視頻教程通過form發送數據的影響,我以爲應該選form-data。百度一番才瞭解到postman的Body四種選項的區別,form-data一般傳文件選擇,x-www-form-urlencoded傳鍵值對,也就是get方式?後的內容,raw傳任意格式的文本,binary二進制。詳細的介紹見網址:https://blog.csdn.net/ye1992/article/details/49998511。將類型選擇爲x-www-form-urlencoded,服務端程序終於正常接收數據了。
第二個關鍵點,POST參數的驗證。爲了傳遞方便,將參數作爲結構,將參數的檢查作爲結構的成員函數,即方法。時間戳驗證,go的time包來處理時間,將字符串轉化爲time類型要注意時區問題,還有go專門的時間段的概念。簽名驗證通過crypto/md5包內md5函數實現。
相關代碼:
//服務端,處理POST請求
func (c *MainController) Post() {
var inp inparam
inp.appkey = c.GetString("appKey")
inp.jsondata = c.GetString("jsonData")
inp.method = c.GetString("method")
inp.timestamp = c.GetString("timestamp")
inp.sign = c.GetString("sign")
//檢查post參數
var rtcode int
var rtmsg string
var rtjson string
rtcode, rtmsg = inp.Check()
if rtcode < 0 {
c.Data["json"] = `{"state":0, "msg":"` + rtmsg + `","jsonData":{},"code":null}`
c.ServeJSON()
return
}
//根據方法,調用函數
if inp.method == "queryMember" {
rtcode, rtmsg, rtjson = queryMember(inp.jsondata)
} else if inp.method == "updateIntegral" {
rtcode, rtmsg, rtjson = updateIntegral(inp.jsondata)
} else {
rtcode = -1
rtmsg = "不支持的方法"
}
//返回信息
if rtcode < 0 {
c.Data["json"] = `{"state":0, "msg":"` + rtmsg + `","jsonData":{},"code":null}`
} else {
c.Data["json"] = `{"state":1, "msg":"成功","jsonData":` + rtjson + `,"code":null}`
}
c.ServeJSON()
}
//參數結構的成員函數,檢查post參數
func (this inparam) Check() (rtcode int, rtmsg string) {
//返回編碼 成功1 失敗-1
//檢查時間戳
const base_format = "2006-01-02 15:04:05"
tin, _ := time.ParseInLocation(base_format, this.timestamp, time.Local)
tsys := time.Now()
if tsys.Sub(tin).Minutes() > 2 || tin.Sub(tsys).Minutes() > 2 {
rtcode = -1
rtmsg = "時間戳超時"
return rtcode, rtmsg
}
//檢查簽名
strparam := "appKey" + this.appkey + "jsonData" + this.jsondata + "method" + this.method + "timestamp" + this.timestamp
has := md5.Sum([]byte(strparam))
md5str1 := fmt.Sprintf("%x", has)
if md5str1 != this.sign {
rtcode = -1
rtmsg = "簽名不正確"
return rtcode, rtmsg
}
rtcode = 1
//返回
return rtcode, rtmsg
}
後記:使用beego,請訪問beego的官網,https://beego.me/,裏邊的開發文檔挺全面的,MVC的概念要理解。
go的標準庫資料,請訪問https://studygolang.com/pkgdoc,這是官方文檔的中文版,最全最權威。