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大礼包。最后,祝您早日实现财务自由,还请给个赞,谢谢!

相关推荐
倔强的石头1062 分钟前
【C++指南】类和对象(九):内部类
开发语言·c++
鸽鸽程序猿3 分钟前
【算法】【优选算法】宽搜(BFS)中队列的使用
算法·宽度优先·队列
Jackey_Song_Odd3 分钟前
C语言 单向链表反转问题
c语言·数据结构·算法·链表
Watermelo6177 分钟前
详解js柯里化原理及用法,探究柯里化在Redux Selector 的场景模拟、构建复杂的数据流管道、优化深度嵌套函数中的精妙应用
开发语言·前端·javascript·算法·数据挖掘·数据分析·ecmascript
乐之者v12 分钟前
leetCode43.字符串相乘
java·数据结构·算法
A懿轩A1 小时前
C/C++ 数据结构与算法【数组】 数组详细解析【日常学习,考研必备】带图+详细代码
c语言·数据结构·c++·学习·考研·算法·数组
古希腊掌管学习的神1 小时前
[搜广推]王树森推荐系统——矩阵补充&最近邻查找
python·算法·机器学习·矩阵
云边有个稻草人1 小时前
【优选算法】—复写零(双指针算法)
笔记·算法·双指针算法
半盏茶香1 小时前
在21世纪的我用C语言探寻世界本质 ——编译和链接(编译环境和运行环境)
c语言·开发语言·c++·算法
忘梓.2 小时前
解锁动态规划的奥秘:从零到精通的创新思维解析(3)
算法·动态规划