当前位置: 首页 > news >正文

Golang JSON 标准库用法详解

JSON (JavaScript Object Notation) 是一种轻量级的数据交换格式,Go语言的标准库encoding/json提供了强大的JSON处理能力。下面我将详细介绍各种用法并提供示例代码。

1. 基本编码(Marshal)

将Go数据结构转换为JSON字符串。

package mainimport ("encoding/json""fmt""log"
)type Person struct {Name    string `json:"name"`          // 字段标签指定JSON键名Age     int    `json:"age"`           // 基本类型字段Address string `json:"address"`       // 字符串字段Hobbies []string `json:"hobbies"`     // 切片字段IsAdmin bool   `json:"is_admin"`      // 布尔字段private string // 小写开头字段不会被导出
}func main() {// 创建一个Person实例p := Person{Name:    "Alice",Age:     30,Address: "123 Main St",Hobbies: []string{"reading", "hiking"},IsAdmin: true,private: "secret", // 这个字段不会被编码}// 将结构体编码为JSONjsonData, err := json.Marshal(p)if err != nil {log.Fatal(err)}fmt.Println(string(jsonData))// 输出: {"name":"Alice","age":30,"address":"123 Main St","hobbies":["reading","hiking"],"is_admin":true}
}

2. 美化输出(Indent)

使用MarshalIndent可以生成格式化的JSON输出。

func main() {p := Person{Name:    "Bob",Age:     25,Address: "456 Oak Ave",Hobbies: []string{"gaming", "coding"},}// 使用MarshalIndent美化输出jsonData, err := json.MarshalIndent(p, "", "  ")if err != nil {log.Fatal(err)}fmt.Println(string(jsonData))/*输出:{"name": "Bob","age": 25,"address": "456 Oak Ave","hobbies": ["gaming","coding"],"is_admin": false}*/
}

3. 基本解码(Unmarshal)

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

func main() {// JSON字符串jsonStr := `{"name": "Charlie","age": 35,"address": "789 Pine Rd","hobbies": ["swimming", "photography"],"is_admin": true}`// 解码JSON到Person结构体var p Personerr := json.Unmarshal([]byte(jsonStr), &p)if err != nil {log.Fatal(err)}fmt.Printf("%+v\n", p)// 输出: {Name:Charlie Age:35 Address:789 Pine Rd Hobbies:[swimming photography] IsAdmin:true private:}
}

4. 处理未知结构的JSON

使用map[string]interface{}interface{}处理未知结构的JSON。

func main() {// 复杂的JSON数据jsonStr := `{"name": "Dave","age": 40,"metadata": {"department": "IT","role": "manager","permissions": ["read", "write", "delete"]}}`// 解码到空接口var data interface{}err := json.Unmarshal([]byte(jsonStr), &data)if err != nil {log.Fatal(err)}// 类型断言访问数据m := data.(map[string]interface{})fmt.Println("Name:", m["name"])fmt.Println("Age:", m["age"])// 访问嵌套数据metadata := m["metadata"].(map[string]interface{})fmt.Println("Department:", metadata["department"])fmt.Println("Permissions:", metadata["permissions"])
}

5. 流式处理(Encoder/Decoder)

对于大文件或网络流,可以使用流式处理。

编码器示例(Encoder)

package mainimport ("encoding/json""os"
)func main() {type Book struct {Title  string `json:"title"`Author string `json:"author"`Year   int    `json:"year"`}books := []Book{{"The Go Programming Language", "Alan A. A. Donovan", 2015},{"Effective Go", "The Go Authors", 2009},}// 创建文件file, err := os.Create("books.json")if err != nil {panic(err)}defer file.Close()// 创建JSON编码器encoder := json.NewEncoder(file)// 设置缩进(可选)encoder.SetIndent("", "  ")// 编码数据到文件err = encoder.Encode(books)if err != nil {panic(err)}
}

解码器示例(Decoder)

package mainimport ("encoding/json""fmt""os"
)func main() {// 打开JSON文件file, err := os.Open("books.json")if err != nil {panic(err)}defer file.Close()// 创建JSON解码器decoder := json.NewDecoder(file)var books []struct {Title  string `json:"title"`Author string `json:"author"`}// 解码JSON数据err = decoder.Decode(&books)if err != nil {panic(err)}// 打印结果for _, book := range books {fmt.Printf("%s by %s\n", book.Title, book.Author)}
}

6. 自定义编码/解码

可以通过实现json.Marshalerjson.Unmarshaler接口来自定义编码和解码行为。

package mainimport ("encoding/json""fmt""strings""time"
)// 自定义时间格式
type CustomTime struct {time.Time
}const layout = "2006-01-02"// 实现Marshaler接口
func (ct CustomTime) MarshalJSON() ([]byte, error) {return []byte(`"` + ct.Time.Format(layout) + `"`), nil
}// 实现Unmarshaler接口
func (ct *CustomTime) UnmarshalJSON(data []byte) error {s := strings.Trim(string(data), `"`)t, err := time.Parse(layout, s)if err != nil {return err}ct.Time = treturn nil
}type Event struct {Name      string     `json:"name"`Timestamp CustomTime `json:"timestamp"`
}func main() {// 编码示例event := Event{Name:      "Product Launch",Timestamp: CustomTime{time.Now()},}jsonData, err := json.Marshal(event)if err != nil {panic(err)}fmt.Println(string(jsonData))// 输出: {"name":"Product Launch","timestamp":"2023-04-01"}// 解码示例jsonStr := `{"name":"Team Meeting","timestamp":"2023-04-15"}`var decodedEvent Eventerr = json.Unmarshal([]byte(jsonStr), &decodedEvent)if err != nil {panic(err)}fmt.Printf("%+v\n", decodedEvent)// 输出: {Name:Team Meeting Timestamp:{Time:2023-04-15 00:00:00 +0000 UTC}}
}

7. 处理JSON标签选项

JSON标签可以包含额外的选项来控制编解码行为。

package mainimport ("encoding/json""fmt"
)type User struct {ID        int    `json:"id"`                     // 常规字段Username  string `json:"username"`               // 常规字段Password  string `json:"-"`                      // 忽略字段Email     string `json:"email,omitempty"`        // 如果为空则忽略LastLogin int64  `json:"last_login,omitempty"`   // 如果为零值则忽略IsActive  bool   `json:"is_active,string"`      // 编码为字符串
}func main() {user := User{ID:        1,Username:  "johndoe",Password:  "secret",LastLogin: 0,       // 零值IsActive:  true,}jsonData, err := json.Marshal(user)if err != nil {panic(err)}fmt.Println(string(jsonData))// 输出: {"id":1,"username":"johndoe","is_active":"true"}
}

8. 处理HTML特殊字符

默认情况下,JSON编码器会转义HTML特殊字符。

package mainimport ("encoding/json""fmt"
)func main() {data := map[string]string{"message": "<script>alert('xss')</script>",}jsonData, err := json.Marshal(data)if err != nil {panic(err)}fmt.Println(string(jsonData))// 输出: {"message":"\u003cscript\u003ealert('xss')\u003c/script\u003e"}
}

如果需要禁用HTML转义:

package mainimport ("bytes""encoding/json""fmt"
)func main() {data := map[string]string{"message": "<script>alert('xss')</script>",}buf := new(bytes.Buffer)encoder := json.NewEncoder(buf)encoder.SetEscapeHTML(false) // 禁用HTML转义err := encoder.Encode(data)if err != nil {panic(err)}fmt.Println(buf.String())// 输出: {"message":"<script>alert('xss')</script>"}
}

9. 处理原始JSON消息(RawMessage)

json.RawMessage可以用来延迟解析或传递原始JSON数据。

package mainimport ("encoding/json""fmt"
)type Message struct {Type string          `json:"type"`Data json.RawMessage `json:"data"` // 原始JSON数据
}type TextContent struct {Text string `json:"text"`
}type ImageContent struct {URL  string `json:"url"`Alt  string `json:"alt"`
}func main() {// 模拟接收到的JSON消息jsonStr := `{"type": "image","data": {"url": "https://example.com/image.jpg","alt": "Example image"}}`var msg Messageerr := json.Unmarshal([]byte(jsonStr), &msg)if err != nil {panic(err)}switch msg.Type {case "text":var content TextContenterr = json.Unmarshal(msg.Data, &content)fmt.Println("Text:", content.Text)case "image":var content ImageContenterr = json.Unmarshal(msg.Data, &content)fmt.Println("Image URL:", content.URL, "Alt:", content.Alt)}// 输出: Image URL: https://example.com/image.jpg Alt: Example image
}

10. 处理JSON数组

处理JSON数组数据。

package mainimport ("encoding/json""fmt"
)func main() {// JSON数组字符串jsonStr := `[{"name": "Alice", "age": 25},{"name": "Bob", "age": 30},{"name": "Charlie", "age": 35}]`// 解码到结构体切片var people []struct {Name string `json:"name"`Age  int    `json:"age"`}err := json.Unmarshal([]byte(jsonStr), &people)if err != nil {panic(err)}for _, p := range people {fmt.Printf("%s is %d years old\n", p.Name, p.Age)}/*输出:Alice is 25 years oldBob is 30 years oldCharlie is 35 years old*/
}

总结

Go的encoding/json包提供了强大的JSON处理能力,包括:

  1. 结构体与JSON的相互转换(Marshal/Unmarshal)
  2. 流式处理(Encoder/Decoder)
  3. 自定义编解码行为
  4. 处理复杂和动态JSON结构
  5. 各种标签选项控制编解码行为
http://www.lqws.cn/news/556885.html

相关文章:

  • Foundry测试实战:解锁区块链测试新姿势
  • Java 大视界 -- Java 大数据机器学习模型在金融市场高频交易策略优化与风险控制中的应用(327)
  • 单调栈一文深度解析
  • NLP——文本预处理(下)
  • 翻译服务器
  • Redis高级数据结构深度解析:BitMap、布隆过滤器、HyperLogLog与Geo应用实践
  • 趣味数据结构之——数组
  • Java 使用 Easy Excel 进行 Excel 数据导入导出
  • 一分钟了解思路链提示词(Chain-of-thought Prompting)
  • uni-app manifest.json 配置:定制化应用的各项功能和行为
  • 基于Pandas和FineBI的昆明职位数据分析与可视化实现(二)- 职位数据清洗与预处理
  • 《自动控制原理 》- 第 1 章 自动控制的基本原理与方式
  • Linux基本指令篇 —— more指令
  • PostgreSQL 中,若需显示 不在 `IN` 子句列表中的数据
  • SQL常用命令
  • 阿里云Ubuntu服务器上安装MySQL并配置远程连接
  • 网络缓冲区
  • Solidity学习 - 错误处理
  • ffpaly播放 g711a音频命令
  • 【学习笔记】深入理解Java虚拟机学习笔记——第12章 Java内存模型与线程
  • 设计模式之抽象工厂模式
  • Docker 入门教程(五):Docker 命令思维导图
  • 【分布式机架感知】分布式机架感知能力的主流存储系统与数据库软件
  • 微处理原理与应用篇---STM32寄存器控制GPIO
  • 矩阵的条件数(Condition Number of a Matrix)
  • 华为云Flexus+DeepSeek征文 | 基于华为云ModelArts Studio安装NoteGen AI笔记应用程序
  • Learning PostgresSQL读书笔记: 第11章 Transactions, MVCC, WALs, and Checkpoints
  • 基于Docker的mosquitto安装测试
  • FPGA设计的上板调试
  • python多线程详细讲解