初学golang,在demo项目中接入sms短信服务,需要通过第三方的接口校验验证码。
共使用到以下三个包:
"encoding/json" //json解析相关
"io/ioutil" //解析httpResponse的body
"net/http" //发起http请求
//校验收到的验证码
func VerifyCode(phone, code string) (bool, error) {
// json
contentType := "application/json"
data := mapToJSON(&map[string]interface{}{
"phone": phone,
"code": code,
"appkey": APP_KEY,
"zone": DEFAULT_ZONE,
})
resp, err := http.Post(VERIFY_URL, contentType, strings.NewReader(data))
if err != nil {
fmt.Printf("post failed, err:%v\n", err)
return false, err
}
defer resp.Body.Close()
b, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Printf("get resp failed, err:%v\n", err)
return false, err
}
//json序列化成map 解析MOB验证接口的返回值
var tempMap map[string]interface{}
err = json.Unmarshal([]byte(b), &tempMap)
if err != nil {
fmt.Printf("parse resp failed, err:%v\n", err)
return false, err
}
//根据接口返回状态码 判断验证码结果
switch tempMap["status"] {
case 200:
return true, nil
case 405:
fmt.Println("code 405 int")
return true, nil
default:
return false,errors.New(tempMap["error"].(string))
}
}
出现的问题:
200、468如{"status":200}、{"status":468,"error":"Illegal check request."}
case 200:
return true, nil
case 405:
fmt.Println("code 405 int")
return true, nil
default:
return false,errors.New(tempMap["error"].(string))
结果发现switch始终走的都是default分支,调试发现这里解析得到的status根本不是int型的,而是float64:
正是因此,switch没有进入200或者其他状态码的分支,于是可以对代码进行修改:
switch int(tempMap["status"].(float64))
先对map中value类型为interface{}的数据进行float64的断言,再通过强转变为int类型,于是能够正确地进入switch分支。
JSON解析数据的类型规则func Unmarshal(data []byte, v interface{})map[string]interface{}
-
bool, for JSON booleans
-
float64, for JSON numbers //这就是本次问题产生的原因
-
string, for JSON strings
-
[]interface{}, for JSON arrays
-
map[string]interface{}, for JSON objects
-
nil for JSON null