概念
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 main
import (
"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 IT
err := 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 IT2
err = 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")
}
}
}