概念
JSON是,一种格式,一种跨语言的语言(很多语言,都对它的库有支持),目的是进行数据交换,尤其用于Web 服务端程序和客户端之间的数据通信。JSON (JavaScript Object Notation)(object=物体,目的,notation=注释,评注)是一种比 XML 更轻量级的数据交换格式,在易于人们阅读和编写的同时,也易于程序解析和生成。尽管 JSON 是 JavaScript 的一个子集,但 JSON 采用完全独立于编程语言的文本格式,且表现为键/值对集合的文本描述形式(类似一些编程语言中的字典结构),这使它成为较为理想的、跨平台、跨语言的数据交换语言。实例如图
开发者可以用 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实例![]() 结构体 ![]() |
| 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>结果: ![]() |
方式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>是缩进结果: ![]() |
|
推荐都增加一个校验错误的if 判断![]() |
||
| 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- 若需要小写或者其他改写,则 struct tag为
<font style="color:rgb(0,0,0);">json:”…key的名字”</font>

- 若希望修改value输出为string/…其他类型,则 struct tag为
json:", 类型"
结果
- 若希望此字符(包括key和value)不会输出到屏幕,则 struct tag为
json:"-"
通过map生成JSON
基本与通过结构体生成JSON相同

解码JSON
JSON解析到结构体
- 引入包
**<font style="color:rgb(0,0,128);">import </font>**<font style="color:rgb(0,128,0);">"encoding/json" </font> - 按照JSON,定义结构体IT
- 创建变量两个
创建变量jsonBuf保存JSON,记得用反引号...+ 定义一个结构体变量tmp,待会用以存储JSON解析后的结构题 - 解码
- 函数为Unmarshal

err := json,Unmarshal([]byte(变量jsonBuf), &tmp)
第一个为JSON,第二为解码后存储近结构体的tmp,其中,第二个参数一定要地址传递!
- 函数为Unmarshal
- 若只需要局部解码,
**可以在结构体定义和变量声明上缩减,其他步骤与上相同,具体看实例**
实例如下:
package mainimport ("encoding/json""fmt")type IT struct {Company string `json:"company"`Subjects []string `json:"subjects"`IsOk bool `json:"isok"`Price float64 `json:"price"`}func main() {b := []byte(`{"company": "itcast","subjects": ["Go","C++","Python","Test"],"isok": true,"price": 666.666}`)var t ITerr := json.Unmarshal(b, &t)if err != nil {fmt.Println("json err:", err)}fmt.Println(t)//运行结果:{itcast [Go C++ Python Test] true 666.666}//只想要 Subjects 字段type IT2 struct {Subjects []string `json:"subjects"`}var t2 IT2err = json.Unmarshal(b, &t2)if err != nil {fmt.Println("json err:", err) }fmt.Println(t2)//运行结果:{[Go C++ Python Test]}}
JSON解码到map
基本步骤与上相同,只有变量和打印结果不同
区别:结构体对字段打印的很清晰,就是写结构题非常麻烦,map很短很直接,但是类型判断需借助类型断言,具体看下方
JSON解码到interface
func main() {b := []byte(`{"company": "itcast","subjects": ["Go","C++","Python","Test"],"isok": true,"price": 666.666}`)var t interface{}err := json.Unmarshal(b, &t)if err != nil {fmt.Println("json err:", err)}fmt.Println(t)//使用断言判断类型m := t.(map[string]interface{})for k, v := range m {switch vv := v.(type) {case string:fmt.Println(k, "is string", vv)case int:fmt.Println(k, "is int", vv)case float64:fmt.Println(k, "is float64", vv)case bool:fmt.Println(k, "is bool", vv)case []interface{}:fmt.Println(k, "is an array:")for i, u := range vv {fmt.Println(i, u)}default:fmt.Println(k, "is of a type I don't know how to handle")}}}





