【发布时间】:2021-01-13 14:47:19
【问题描述】:
我正在尝试学习 golang,并且正在尝试将旧的 PHP 脚本“移植”到 golang。 现在我有一个关于“解码”http.Client POST 请求正文的问题。 (我可能年纪大了,无法学习一门新语言……)
我的代码看起来像这样(缩短):
var my_client = &http.Client{
Transport: my_Trans, // Defined elsewhere
Timeout: my_TimeOut, // Defined elsewhere
}
logininfo := map[string]interface{}{"username": user, "password": pw}
payload, _ := json.Marshal(logininfo)
request, _ := http.NewRequest("POST", "https://abc.def.com", bytes.NewBuffer(payload))
request.Header.Set("Content-Type", "application/json")
response, err := my_client.Do(request)
defer response.Body.Close()
log.Printf("response.Body")
log.Printf("%s", response.Body)
这会输出如下所示的响应正文:
2021/01/13 13:50:31 response.Body
2021/01/13 13:50:31 {{"data":{"state":1,"id":"1234567890","Token":"ABCDEF0123456","lastloginip":"192.168.10.1","lastlogintime":1600000000},"error":{"code":0,"description":"0"}}
}
我想从该正文中提取两个字段“id”和“Token”。 我想出的是以下内容:
type my_loginResult struct {
Data struct {
State int `json:"state"`
Id string `json:"id"`
Token string `json:"Token"`
Lastloginip string `json:"lastloginip"`
Lastlogintime int `json:"lastlogintime"`
}
Error struct {
Code int `json:"code"`
Description string `json:"description"`
}
}
resultjson := my_loginResult{}
tmp_body, _ := ioutil.ReadAll(response.Body)
json.Unmarshal(tmp_body, &resultjson)
id = resultjson.Data.Id
token = resultjson.Data.Token
这是“解码”身体的“正确”和最有效的方式吗?
在 PHP 中我可以做到:
id = $response->body->data->id;
token = $response->body->data->Token;
问候,
丹
【问题讨论】:
-
我觉得不错,你有什么问题?
-
请注意,尽管 Go 风格更喜欢 pascalCase 而不是 snake_case 的名称。
-
如果这是你输入的json,那么它是无效的:
{{"data":{"state":1,"id":"1234567890","Token":"ABCDEF0123456","lastloginip":"192.168.10.1","lastlogintime":1600000000},"error":{"code":0,"description":"0"}}}。你输入的 json 到底是什么? -
请注意,您忽略了从
json.Unmarshal返回的错误。检查错误,总是!它会告诉你无效的 json。 -
@D.M.J.尝试这样的事情:play.golang.org/p/KUJrw9YPW2o -- 1. 不要忽略错误。 2. 只指定您需要的那些字段是可以的。 3.如果你的json在
io.Reader后面,你可以使用json.Decoder,它应该更有效地解码json流。