如何在Golang中处理JSON数据

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)

我们使用Marshalu1结构编码为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教程。

赞(0) 打赏

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏