英文:
How to retrieve object from Go http.Request?
问题
我有一个可以接收HTTP GET参数的工作应用程序。到目前为止,它们一直是字符串和整数,并且通过以下方式成功获取每个字段:
http.Request.FormValue("field")
但是现在我在参数中添加了一个简单对象的数组,我不知道如何将其转换为Go结构的切片。
所涉及的数组是:
mods:[{
name : x,
max : 1,
min : 2
},{
name:y,...
}]
所以我不确定如何继续将其映射到Go结构。我应该先创建结构,然后使用JSON映射r.FormValue的结果吗?
英文:
I have a working app that recieves HTTP GET parameters. They've been Strings and ints until now and it has worked fine getting each field using
http.Request.FormValue("field")
But now I've added an array of simple objects in the parameters and I don't know how to transform it to a slice of Go structs.
The array in question is
mods:[{
name : x,
max : 1,
min : 2
},{
name:y,...
}]
So I'm not sure how to proceed to map it to a Go struct. Should I create the struct first and map the result of r.FormValue using JSON?
答案1
得分: 2
假设你想获取一组GitHub用户并打印他们的昵称(api.github.com
中的Login
字段)。
给定一个用户数组示例:
[{
"login": "simonjefford",
"id": 136,
"avatar_url": "https://avatars1.githubusercontent.com/u/136?v=3",
"gravatar_id": "",
"url": "https://api.github.com/users/simonjefford",
"html_url": "https://github.com/simonjefford",
"followers_url": "https://api.github.com/users/simonjefford/followers",
"following_url": "https://api.github.com/users/simonjefford/following{/other_user}",
"gists_url": "https://api.github.com/users/simonjefford/gists{/gist_id}",
"starred_url": "https://api.github.com/users/simonjefford/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/simonjefford/subscriptions",
"organizations_url": "https://api.github.com/users/simonjefford/orgs",
"repos_url": "https://api.github.com/users/simonjefford/repos",
"events_url": "https://api.github.com/users/simonjefford/events{/privacy}",
"received_events_url": "https://api.github.com/users/simonjefford/received_events",
"type": "User",
"site_admin": false
}]
你需要一个适当的结构来处理它:
type Users []struct {
Login string `json:"login"`
ID int `json:"id"`
AvatarURL string `json:"avatar_url"`
GravatarID string `json:"gravatar_id"`
URL string `json:"url"`
HTMLURL string `json:"html_url"`
FollowersURL string `json:"followers_url"`
FollowingURL string `json:"following_url"`
GistsURL string `json:"gists_url"`
StarredURL string `json:"starred_url"`
SubscriptionsURL string `json:"subscriptions_url"`
OrganizationsURL string `json:"organizations_url"`
ReposURL string `json:"repos_url"`
EventsURL string `json:"events_url"`
ReceivedEventsURL string `json:"received_events_url"`
Type string `json:"type"`
SiteAdmin bool `json:"site_admin"`
}
我建议你使用json-to-go来根据JSON生成一个漂亮干净的结构。
然后你可以进行以下操作:
package main
import (
"fmt"
"encoding/json"
"net/http"
"log"
"io/ioutil"
)
func main() {
response, err := http.Get("https://api.github.com/users?since=135")
if err != nil {
log.Fatal(err)
} else {
defer response.Body.Close()
users := UnmarshalUsers(response)
for _, u := range users {
// 打印每个用户的登录昵称
fmt.Println(u.Login)
}
}
}
func UnmarshalUsers(r *http.Response) Users {
body, err := ioutil.ReadAll(r.Body)
if err != nil {
panic(err)
}
var users Users
err = json.Unmarshal(body, &users)
if err != nil {
panic(err)
}
return users
}
其中UnmarshalUsers
函数定义如下:
func UnmarshalUsers(r *http.Response) Users {
body, err := ioutil.ReadAll(r.Body)
if err != nil {
panic(err)
}
var users Users
err = json.Unmarshal(body, &users)
if err != nil {
panic(err)
}
return users
}
英文:
Let's say you want to fetch a set of github users and want to print their nicknames (Login
field in api.github.com
).
Given a User array example:
[{
"login": "simonjefford",
"id": 136,
"avatar_url": "https://avatars1.githubusercontent.com/u/136?v=3",
"gravatar_id": "",
"url": "https://api.github.com/users/simonjefford",
"html_url": "https://github.com/simonjefford",
"followers_url": "https://api.github.com/users/simonjefford/followers",
"following_url": "https://api.github.com/users/simonjefford/following{/other_user}",
"gists_url": "https://api.github.com/users/simonjefford/gists{/gist_id}",
"starred_url": "https://api.github.com/users/simonjefford/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/simonjefford/subscriptions",
"organizations_url": "https://api.github.com/users/simonjefford/orgs",
"repos_url": "https://api.github.com/users/simonjefford/repos",
"events_url": "https://api.github.com/users/simonjefford/events{/privacy}",
"received_events_url": "https://api.github.com/users/simonjefford/received_events",
"type": "User",
"site_admin": false
}]
You need a proper struct to handle it:
type Users []struct {
Login string `json:"login"`
ID int `json:"id"`
AvatarURL string `json:"avatar_url"`
GravatarID string `json:"gravatar_id"`
URL string `json:"url"`
HTMLURL string `json:"html_url"`
FollowersURL string `json:"followers_url"`
FollowingURL string `json:"following_url"`
GistsURL string `json:"gists_url"`
StarredURL string `json:"starred_url"`
SubscriptionsURL string `json:"subscriptions_url"`
OrganizationsURL string `json:"organizations_url"`
ReposURL string `json:"repos_url"`
EventsURL string `json:"events_url"`
ReceivedEventsURL string `json:"received_events_url"`
Type string `json:"type"`
SiteAdmin bool `json:"site_admin"`
}
I suggest you to use json-to-go to have a nice a clean struct given a json.
Then you can do the following:
package main
import (
"fmt"
"encoding/json"
"net/http"
"log"
"io/ioutil"
)
func main() {
response, err := http.Get("https://api.github.com/users?since=135")
if err != nil {
log.Fatal(err)
} else {
defer response.Body.Close()
users := UnmarshalUsers(response)
for _, u := range users {
//Print each user's Login nickname
fmt.Println(u.Login)
}
}
}
Where UnmarshalUsers
is
func UnmarshalUsers(r *http.Response) Users {
body, err := ioutil.ReadAll(r.Body)
if err != nil {
panic(err)
}
var users Users
err = json.Unmarshal(body, &users)
if err != nil {
panic(err)
}
return users
}
答案2
得分: 0
请查看encoding/json包。在Go语言中,你需要将Go结构体编组(marshal)和解组(unmarshal)为它们的编码形式。这并不是一个快速简单的过程,但对于像Go这样的强类型语言来说,这是一个很好的现代解决方案。
在你的情况下,你需要创建一个与你要提取的JSON结构相匹配的结构体,然后将JSON解组为你创建的结构体类型的变量。
英文:
Check out the encoding/json package. In Go, you have to marshal and unmarshal your Go structures into and out of their encoding. It isn't quick an easy, but it's an good modern solution for a strictly typed language like Go.
In your case, you'll want to create a struct that matches the structure of the json you are trying to extract, and then unmarshal the json into a variable of the struct type you created.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论