概念

JSON是,一种格式,一种跨语言的语言(很多语言,都对它的库有支持),目的是进行数据交换,尤其用于Web 服务端程序和客户端之间的数据通信。
JSON (JavaScript Object Notation)(object=物体,目的notation=注释,评注)是一种比 XML 更轻量级的数据交换格式,在易于人们阅读和编写的同时,也易于程序解析和生成。尽管 JSON 是 JavaScript 的一个子集,但 JSON 采用完全独立于编程语言的文本格式,且表现为键/值对集合的文本描述形式(类似一些编程语言中的字典结构),这使它成为较为理想的、跨平台、跨语言的数据交换语言。实例如图
JOSN处理 - 图1 开发者可以用 JSON 传输简单的字符串、数字、布尔值,也可以传输一个数组,或者一个更复杂的复合结构。在 Web 开发领域中, JSON 被广泛应用于 Web 服务端程序和客户端之间的数据通信。 Go 语言内建对 JSON 的支持。使用 Go 语言内置的 encoding/json 标准库,开发者可以轻松使用 Go 程序生成和解析 JSON 格式的数据,JSON 官方网站:http://www.json.org/ 在线格式化:http://www.json.cn/(强烈建议在编码前,把JSON数据放到里面校验一下)

编码JSON

通过结构体生成JSON

具体步骤 实例
1
引入包
**<font style="color:rgb(0,0,128);">import </font>**<font style="color:rgb(0,128,0);">"encoding/json" </font>
2.1
定义结构体,type
1. 可以观察到,JSON 采用完全独立于编程语言的文本格式,且表现为键/值对集合的文本描述形式,于是我们结构体成员变量名为key,类型为value类型
2. 结构体成员变量名必须大写,若要修改如大小写,可进行二次修改,见下方备注
JSON实例
JOSN处理 - 图2
结构体
JOSN处理 - 图3
2.2
定义结构体变量
定义结构体变量 <font style="color:rgb(0,0,0);">t1 := IT{</font><font style="color:rgb(0,128,0);">"itcast"</font><font style="color:rgb(0,0,0);">, []</font><font style="color:rgb(0,0,128);">string</font><font style="color:rgb(0,0,0);">{</font><font style="color:rgb(0,128,0);">"Go"</font><font style="color:rgb(0,0,0);">, </font><font style="color:rgb(0,128,0);">"C++"</font><font style="color:rgb(0,0,0);">,</font><font style="color:rgb(0,128,0);">"Python"</font><font style="color:rgb(0,0,0);">,</font><font style="color:rgb(0,128,0);">"Test"</font><font style="color:rgb(0,0,0);">},</font><font style="color:rgb(0,0,128);">true</font><font style="color:rgb(0,0,0);">,</font><font style="color:rgb(128,0,128);">666.666</font><font style="color:rgb(0,0,0);">}</font>
3
编码成jason
方式1:
使用 <font style="color:rgb(0,0,0);">json.Marshal()</font>函数可以对一组数据进行 JSON 格式的编码。 json.Marshal()函数的声明如下:
**<font style="color:rgb(0,0,128);">func </font>**<font style="color:rgb(0,0,0);">Marshal(v </font>**<font style="color:rgb(0,0,128);">interface</font>**<font style="color:rgb(0,0,0);">{}) ([]</font><font style="color:rgb(0,0,128);">byte</font><font style="color:rgb(0,0,0);">, </font><font style="color:rgb(0,0,128);">error</font><font style="color:rgb(0,0,0);">) </font>
注意接受任意类型,返回两个变量,一个是切片,一个是error
方式1: <font style="color:rgb(0,128,0);">b, err := json.Marshal(t1)</font>
结果:
JOSN处理 - 图4
方式2:
<font style="color:rgb(0,0,0);">json.MarshalIndent</font>
唯一与方式1的差别是,格式化编码
方式2:
<font style="color:rgb(0,0,0);">b, err := json.MarshalIndent(t1, </font><font style="color:rgb(0,128,0);">""</font><font style="color:rgb(0,0,0);">, </font><font style="color:rgb(0,128,0);">" "</font><font style="color:rgb(0,0,0);">)</font>
<font style="color:rgb(0,0,0);">""</font>是空,<font style="color:rgb(0,0,0);">" "</font>是缩进
结果:
JOSN处理 - 图5
推荐都增加一个校验错误的if 判断
JOSN处理 - 图6
4
打印
尤其注意,要进行string强制类型转换后才可以打印
<font style="color:rgb(0,0,0);">fmt.Println(</font><font style="color:rgb(0,0,128);">string</font><font style="color:rgb(0,0,0);">(b))</font>

:::info 二次编码, struct tag

:::

结构体成员变量名必须大写,结果key首字母默认为大写,那么我们如果希望修改key和value怎么办呢?——则在该结构体成员定义后加 struct tag
  1. 若需要小写或者其他改写, struct tag<font style="color:rgb(0,0,0);">json:”…key的名字”</font>
    JOSN处理 - 图7
    JOSN处理 - 图8
  2. 若希望修改value输出为string/…其他类型,则 struct tagjson:", 类型"
    JOSN处理 - 图9
    结果
    JOSN处理 - 图10
  3. 若希望此字符(包括key和value)不会输出到屏幕,则 struct tagjson:"-"
    JOSN处理 - 图11

通过map生成JSON

基本与通过结构体生成JSON相同

JOSN处理 - 图12

解码JSON

JSON解析到结构体

  1. 引入包**<font style="color:rgb(0,0,128);">import </font>**<font style="color:rgb(0,128,0);">"encoding/json" </font>
  2. 按照JSON,定义结构体IT
  3. 创建变量两个
    创建变量jsonBuf保存JSON,记得用反引号... + 定义一个结构体变量tmp,待会用以存储JSON解析后的结构题
  4. 解码
    1. 函数为Unmarshal
      JOSN处理 - 图13
    2. err := json,Unmarshal([]byte(变量jsonBuf), &tmp)
      第一个为JSON,第二为解码后存储近结构体的tmp,其中,第二个参数一定要地址传递!
  5. 若只需要局部解码,
    **
    可以在结构体定义和变量声明上缩减,其他步骤与上相同,具体看实例**

实例如下:
JOSN处理 - 图14

  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. )
  6. type IT struct {
  7. Company string `json:"company"`
  8. Subjects []string `json:"subjects"`
  9. IsOk bool `json:"isok"`
  10. Price float64 `json:"price"`
  11. }
  12. func main() {
  13. b := []byte(`{
  14. "company": "itcast",
  15. "subjects": [
  16. "Go",
  17. "C++",
  18. "Python",
  19. "Test"
  20. ],
  21. "isok": true,
  22. "price": 666.666
  23. }`)
  24. var t IT
  25. err := json.Unmarshal(b, &t)
  26. if err != nil {
  27. fmt.Println("json err:", err)
  28. }
  29. fmt.Println(t)
  30. //运行结果:{itcast [Go C++ Python Test] true 666.666}
  31. //只想要 Subjects 字段
  32. type IT2 struct {
  33. Subjects []string `json:"subjects"`
  34. }
  35. var t2 IT2
  36. err = json.Unmarshal(b, &t2)
  37. if err != nil {
  38. fmt.Println("json err:", err) }
  39. fmt.Println(t2)
  40. //运行结果:{[Go C++ Python Test]}
  41. }

JSON解码到map

基本步骤与上相同,只有变量和打印结果不同
JOSN处理 - 图15

区别:结构体对字段打印的很清晰,就是写结构题非常麻烦,map很短很直接,但是类型判断需借助类型断言,具体看下方

JSON解码到interface

  1. func main() {
  2. b := []byte(`{
  3. "company": "itcast",
  4. "subjects": [
  5. "Go",
  6. "C++",
  7. "Python",
  8. "Test"
  9. ],
  10. "isok": true,
  11. "price": 666.666
  12. }`)
  13. var t interface{}
  14. err := json.Unmarshal(b, &t)
  15. if err != nil {
  16. fmt.Println("json err:", err)
  17. }
  18. fmt.Println(t)
  19. //使用断言判断类型
  20. m := t.(map[string]interface{})
  21. for k, v := range m {
  22. switch vv := v.(type) {
  23. case string:
  24. fmt.Println(k, "is string", vv)
  25. case int:
  26. fmt.Println(k, "is int", vv)
  27. case float64:
  28. fmt.Println(k, "is float64", vv)
  29. case bool:
  30. fmt.Println(k, "is bool", vv)
  31. case []interface{}:
  32. fmt.Println(k, "is an array:")
  33. for i, u := range vv {
  34. fmt.Println(i, u)
  35. }
  36. default:
  37. fmt.Println(k, "is of a type I don't know how to handle")
  38. }
  39. }
  40. }

JOSN处理 - 图16