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教程。
