15分钟学 Go 第 28 天:JSON处理

第28天:JSON处理

学习目标

在这一节中,我们将重点学习如何在Go语言中处理JSON数据。JSON(JavaScript Object Notation)是一种广泛使用的数据交换格式,其简单性和可读性使其成为与客户端和服务器通信的理想选择。本节的目标是帮助你:

  1. 理解JSON的基本概念。
  2. 学会使用Go标准库中的encoding/json库进行JSON的编码和解码。
  3. 掌握JSON数据的结构化处理,包括结构体,切片和映射。
  4. 实践通过示例代码和实践项目来巩固理解。

JSON基础概念

什么是JSON?

JSON是一种轻量级的数据交换格式,它易于阅读和编写,同时也易于机器解析和生成。

  • 格式示例
json 复制代码
{
  "name": "Alice",
  "age": 30,
  "is_student": false,
  "courses": ["Math", "Science"],
  "address": {
    "street": "123 Main St",
    "city": "Anytown"
  }
}

JSON数据类型

JSON支持以下数据类型:

  • 对象:由键值对组成,使用花括号表示。
  • 数组:有序的值列表,使用方括号表示。
  • 字符串:双引号包围的字符。
  • 数字:整数或浮点数。
  • 布尔值:truefalse
  • 空值:null

Go中的JSON处理

Go语言提供了内置的encoding/json库,用于JSON的编码和解码。我们将通过几个例子来详细说明。

1. JSON编码(Struct to JSON)

示例代码

创建一个简单的结构体,并将其编码为JSON格式。

go 复制代码
package main

import (
    "encoding/json"
    "fmt"
    "log"
)

type Person struct {
    Name      string   `json:"name"`
    Age       int      `json:"age"`
    IsStudent bool     `json:"is_student"`
    Courses   []string `json:"courses"`
    Address   struct {
        Street string `json:"street"`
        City   string `json:"city"`
    } `json:"address"`
}

func main() {
    // 创建一个 Person 实例
    person := Person{
        Name:      "Alice",
        Age:       30,
        IsStudent: false,
        Courses:   []string{"Math", "Science"},
    }
    person.Address.Street = "123 Main St"
    person.Address.City = "Anytown"

    // 将结构体编码为 JSON
    jsonData, err := json.Marshal(person)
    if err != nil {
        log.Fatalf("Error encoding JSON: %s", err)
    }

    fmt.Println(string(jsonData))
}
代码解析
  1. 定义结构体Person结构体被定义并包含了多个字段,每个字段用JSON标签进行标注。
  2. 实例化结构体 :创建person实例并初始化字段。
  3. JSON编码 :使用json.Marshal方法将结构体编码为JSON格式。如果成功,编码结果将存储在jsonData中。
  4. 输出JSON :使用fmt.Println打印出结果。

2. JSON解码(JSON to Struct)

示例代码

将JSON字符串解码为Go结构体。

go 复制代码
package main

import (
    "encoding/json"
    "fmt"
    "log"
)

func main() {
    jsonStr := `{
        "name": "Alice",
        "age": 30,
        "is_student": false,
        "courses": ["Math", "Science"],
        "address": {
            "street": "123 Main St",
            "city": "Anytown"
        }
    }`

    var person Person

    // 将 JSON 解码到结构体
    if err := json.Unmarshal([]byte(jsonStr), &person); err != nil {
        log.Fatalf("Error decoding JSON: %s", err)
    }

    fmt.Printf("Name: %s, Age: %d, Is Student: %t\n", person.Name, person.Age, person.IsStudent)
    fmt.Printf("Courses: %v\n", person.Courses)
    fmt.Printf("Address: %s, %s\n", person.Address.Street, person.Address.City)
}

代码解析

  1. JSON字符串 :定义一个字符串 jsonStr,其中包含有效的JSON数据。
  2. 解码过程 :使用json.Unmarshal将JSON字符串解码为person结构体。需要注意的是,传递的是结构体的地址。
  3. 输出结果:打印各种字段以验证解码是否成功。

3. JSON数组处理

示例代码

处理JSON数组的示例。

go 复制代码
package main

import (
    "encoding/json"
    "fmt"
    "log"
)

type Classroom struct {
    Students []Person `json:"students"`
}

func main() {
    jsonStr := `{
        "students": [
            {"name": "Alice", "age": 30, "is_student": false},
            {"name": "Bob", "age": 22, "is_student": true}
        ]
    }`

    var classroom Classroom

    // 解码 JSON 数组
    if err := json.Unmarshal([]byte(jsonStr), &classroom); err != nil {
        log.Fatalf("Error decoding JSON: %s", err)
    }

    for _, student := range classroom.Students {
        fmt.Printf("Name: %s, Age: %d, Is Student: %t\n", student.Name, student.Age, student.IsStudent)
    }
}

代码解析

  1. 定义Classroom结构体 :包含一个Students字段,类型为[]Person
  2. 解码JSON数组 :解析一个包含学生信息的JSON字符串,并将其映射到Classroom结构体。
  3. 遍历数组:打印每个学生的信息。

JSON与Go的最佳实践

  1. 使用标签:为结构体字段添加适当的JSON标签,以确保JSON数据能够正确映射。
  2. 错误处理:处理JSON编码和解码时的错误,确保代码稳定性。
  3. 保持简单:尽量保持JSON结构的简单性,避免过于复杂的嵌套结构。

代码运行流程图

以下是JSON编码与解码的流程图:

plaintext 复制代码
+-----------------+
|   Start         |
+-----------------+
         |
         v
+-----------------+
| Define Structs  |
| and Variables   |
+-----------------+
         |
         v
+-----------------+
|  Encode JSON    |
|  (Marshal)      |
+-----------------+
         |
         v
+-----------------+
| Output JSON     |
| (Print JSON)    |
+-----------------+
         |
         v
+-----------------+
|  Decode JSON    |
|  (Unmarshal)    |
+-----------------+
         |
         v
+-----------------+
| Access Data     |
| from Structs    |
+-----------------+
         |
         v
+-----------------+
|    End          |
+-----------------+

实战项目:一个简单的API

我们将构建一个简单的HTTP服务器,能够处理JSON请求和响应。

示例代码

go 复制代码
package main

import (
    "encoding/json"
    "log"
    "net/http"
)

type Person struct {
    Name      string `json:"name"`
    Age       int    `json:"age"`
    IsStudent bool   `json:"is_student"`
}

func personHandler(w http.ResponseWriter, r *http.Request) {
    if r.Method == http.MethodPost {
        var person Person
        // 解码请求中的 JSON
        if err := json.NewDecoder(r.Body).Decode(&person); err != nil {
            http.Error(w, err.Error(), http.StatusBadRequest)
            return
        }
        // 处理后返回 JSON
        w.Header().Set("Content-Type", "application/json")
        json.NewEncoder(w).Encode(person)
    } else {
        http.Error(w, "Invalid request method", http.StatusMethodNotAllowed)
    }
}

func main() {
    http.HandleFunc("/person", personHandler)
    log.Println("Listening on :8080")
    log.Fatal(http.ListenAndServe(":8080", nil))
}

代码解析

  1. 定义HTTP处理函数personHandler处理HTTP POST请求,解码请求体中的JSON数据,并返回相应的JSON。
  2. 设置路由 :使用http.HandleFunc将请求路径与处理函数关联。
  3. 启动HTTP服务器 :使用http.ListenAndServe在8080端口监听请求。

使用方式

  1. 启动服务器:

    bash 复制代码
    go run main.go
  2. 使用curl命令测试POST请求:

    bash 复制代码
    curl -X POST -H "Content-Type: application/json" -d '{"name":"Alice", "age":30, "is_student":false}' http://localhost:8080/person
  3. 响应结果:

    json 复制代码
    {
        "name": "Alice",
        "age": 30,
        "is_student": false
    }

练习

  1. 练习1 :修改结构体Person,添加新的字段(如grades),并相应地调整JSON编码和解码。
  2. 练习2 :创建一个包含多个Person实例的JSON数组,并实现相应的解码和输出功能。
  3. 练习3:尝试编写一个更复杂的API,支持获取和添加多个学生信息。

总结

在第28天的学习中,我们深入探讨了Go语言中的JSON处理技术。通过实际示例,我们学会了如何编码和解码JSON数据,处理结构体、数组和HTTP请求。建议你继续通过实际项目来巩固今天所学的知识,逐步提高你的Go语言技能。

参考链接


怎么样今天的内容还满意吗?再次感谢观众老爷的观看,关注GZH:凡人的AI工具箱,回复666,送您价值199的AI大礼包。最后,祝您早日实现财务自由,还请给个赞,谢谢!

相关推荐
卷福同学11 分钟前
【AI编程】AI+高德MCP不到10分钟搞定上海三日游
人工智能·算法·程序员
mit6.82412 分钟前
[Leetcode] 预处理 | 多叉树bfs | 格雷编码 | static_cast | 矩阵对角线
算法
Wy. Lsy21 分钟前
Kotlin基础学习记录
开发语言·学习·kotlin
皮卡蛋炒饭.34 分钟前
数据结构—排序
数据结构·算法·排序算法
方圆想当图灵35 分钟前
ScheduledFutureTask 踩坑实录
后端
二楼后座。36 分钟前
Golang操作MySQL json字段优雅写法
mysql·golang·json
全栈凯哥1 小时前
16.Spring Boot 国际化完全指南
java·spring boot·后端
M1A11 小时前
Java集合框架深度解析:LinkedList vs ArrayList 的对决
java·后端
Tanecious.1 小时前
C++--红黑树
开发语言·c++
Top`1 小时前
Java 泛型 (Generics)
java·开发语言·windows