GoJSON教程展示了如何在Golang中处理JSON数据。
$ go version go version go1.18.1 linux/amd64
我们使用Go版本1.18。
JSON
JSON(JavaScript对象表示法)是一种轻量级数据交换格式。它很容易被人类阅读和编写,并被机器解析和生成。application/json
是JSON的官方互联网媒体类型。JSON文件扩展名为.json
。
encoding/json
包实现了JSON的编码和解码。
去编码成JSON
Marshal
函数将数据编码为JSON。
package main import ( "encoding/json" "fmt" "log" ) type User struct { Id int Name string Occupation string } func main() { u1 := User{1, "John Doe", "gardener"} json_data, err := json.Marshal(u1) if err != nil { log.Fatal(err) } fmt.Println(string(json_data)) users := []User{ {Id: 2, Name: "Roger Roe", Occupation: "driver"}, {Id: 3, Name: "Lucy Smith", Occupation: "teacher"}, {Id: 4, Name: "David Brown", Occupation: "programmer"}, } json_data2, err := json.Marshal(users) if err != nil { log.Fatal(err) } fmt.Println(string(json_data2)) }
在代码示例中,我们将Go结构和结构切片转换为JSON格式。
type User struct { Id int Name string Occupation string }
我们声明了User
结构。
u1 := User{1, "John Doe", "gardener"}
我们创建结构实例。
json_data, err := json.Marshal(u1)
我们使用Marshal
将u1
结构编码为JSON。
fmt.Println(string(json_data))
因为json_data
是字节数组,我们用string
函数将它转换成字符串。
users := []User{ {Id: 2, Name: "Roger Roe", Occupation: "driver"}, {Id: 3, Name: "Lucy Smith", Occupation: "teacher"}, {Id: 4, Name: "David Brown", Occupation: "programmer"}, }
我们有一部分用户。
json_data2, err := json.Marshal(users)
我们使用Marshal
对用户切片进行编码。
fmt.Println(string(json_data2))
我们打印编码的切片。
$ go run encoding.go {"Id":1,"Name":"John Doe","Occupation":"gardener"} [{"Id":2,"Name":"Roger Roe","Occupation":"driver"},{"Id":3,"Name":"Lucy Smith","Occupation":"teacher"}, {"Id":4,"Name":"David Brown","Occupation":"programmer"}]
去解码成JSON
Unmarshal
函数将JSON数据解码为Go值。
package main import ( "encoding/json" "fmt" "log" ) type User struct { Id int Name string Occupation string } func main() { var u1 User data := []byte(`{ "Id" : 1, "Name": "John Doe", "Occupation": "gardener" }`) err := json.Unmarshal(data, &u1) if err != nil { log.Fatal(err) } fmt.Println("Struct is:", u1) fmt.Printf("%s is a %s.\n", u1.Name, u1.Occupation) var u2 []User data2 := []byte(` [ {"Id":2,"Name":"Roger Roe","Occupation":"driver"}, {"Id":3,"Name":"Lucy Smith","Occupation":"teacher"}, {"Id":4,"Name":"David Brown","Occupation":"programmer"} ]`) err2 := json.Unmarshal(data2, &u2) if err2 != nil { log.Fatal(err2) } for i := range u2 { fmt.Println(u2[i]) } }
我们将JSON字符串解码为Go结构和结构切片。
data := []byte(`{ "Id" : 1, "Name": "John Doe", "Occupation": "gardener" }`)
我们有一个转换为字节的JSON对象。
err := json.Unmarshal(data, &u1)
我们使用Unmarshal
将JSON中的u1
结构解码为一个结构。
var u2 []User
我们声明了一片User
结构。
data2 := []byte(` [ {"Id":2,"Name":"Roger Roe","Occupation":"driver"}, {"Id":3,"Name":"Lucy Smith","Occupation":"teacher"}, {"Id":4,"Name":"David Brown","Occupation":"programmer"} ]`)
这是一个将被解码为Go切片的JSON数组。
err2 := json.Unmarshal(data2, &u2)
我们使用Unmarshal
将JSON数组解码为Goslice。
for i := range u2 { fmt.Println(u2[i]) }
我们逐个打印解码后的JSON数组。
$ go run decoding.go Struct is: {1 John Doe gardener} John Doe is a gardener. {2 Roger Roe driver} {3 Lucy Smith teacher} {4 David Brown programmer}
GoJSON漂亮打印
可以使用MarshalIndent
函数漂亮地打印输出。
package main import ( "encoding/json" "fmt" "log" ) func main() { birds := map[string]interface{}{ "sounds": map[string]string{ "pigeon": "coo", "eagle": "squak", "owl": "hoot", "duck": "quack", "cuckoo": "ku-ku", "raven": "cruck-cruck", "chicken": "cluck", "rooster": "cock-a-doodle-do", }, } data, err := json.MarshalIndent(birds, "", " ") if err != nil { log.Fatal(err) } fmt.Println(string(data)) }
在代码示例中,我们有一张鸟叫声地图。输出使用MarshalIndent
进行美化。
$ go run pretty_print.go { "sounds": { "chicken": "cluck", "cuckoo": "ku-ku", "duck": "quack", "eagle": "squak", "owl": "hoot", "pigeon": "coo", "raven": "cruck-cruck", "rooster": "cock-a-doodle-do" } }
我们可以看到输出是缩进的,因此更具可读性。
从文件中读取JSON
下一个示例从文件中读取JSON数据。
[ { "name": "John Doe", "occupation": "gardener", "born": "1992-03-02" }, { "name": "Brian Flemming", "occupation": "teacher", "born": "1967-11-22" }, { "name": "Lucy Black", "occupation": "accountant", "born": "1995-04-07" }, { "name": "John Doe", "occupation": "gardener", "born": "1972-08-30" } ]
这是data.json
文件。
package main import ( "encoding/json" "fmt" "io/ioutil" "log" "os" ) type User struct { Name string Occupation string Born string } func main() { filename, err := os.Open("data.json") if err != nil { log.Fatal(err) } defer filename.Close() data, err := ioutil.ReadAll(filename) if err != nil { log.Fatal(err) } var result []User jsonErr := json.Unmarshal(data, &result) if jsonErr != nil { log.Fatal(jsonErr) } fmt.Println(result) }
该示例从文件中读取JSON数据并将其解码为user
结构的切片。
$ go run read_json.go [{John Doe gardener 1992-03-02} {Brian Flemming teacher 1967-11-22} {Lucy Black accountant 1995-04-07} {John Doe gardener 1972-08-30}]
去JSONHttpClient
net/http
包提供HTTP客户端和服务器实现。
package main import ( "encoding/json" "fmt" "io/ioutil" "log" "net/http" "time" ) type Astronaut struct { Name string Craft string } type people struct { Number int People []Astronaut Message string } func main() { url := "http://api.open-notify.org/astros.json" var netClient = http.Client{ Timeout: time.Second * 10, } res, err := netClient.Get(url) if err != nil { log.Fatal(err) } defer res.Body.Close() body, err := ioutil.ReadAll(res.Body) fmt.Println(body) if err != nil { log.Fatal(err) } astros := people{} jsonErr := json.Unmarshal(body, &astros) if jsonErr != nil { log.Fatal(jsonErr) } fmt.Println(astros) }
该示例使用内置的GoHTTP客户端从Web服务读取数据。我们向服务创建GET请求,该请求返回有关国际空间站宇航员的数据。
$ go run astros.go {3 [{Chris Cassidy ISS} {Anatoly Ivanishin ISS} {Ivan Vagner ISS}] success}
此刻,空间站上有三名宇航员。
在本教程中,我们在Golang中使用了JSON。
列出所有Go教程。