根据接口规范文档要求,需要通过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.youkuaiyun.com/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,这是官方文档的中文版,最全最权威。