1. 简介
JSON即JavaScript对象表示法(JavaScript Object Notation),是一种用于存储和交换数据的格式,是一种可供人类阅读和理解的纯文本格式。
JSON既可以键值对的形式,也可以数组的形式,表示数据。
JSON最初是JavaScript的一个子集,但现在已然独立,为大多数语言所支持。
JSON已经取代XML,成为互联网上存储和交换数据的事实标准。
JSON以下面这种形式描述对象(一系列键值对组合):
- {
- "name": "George",
"age": 40,
"children": ["Bea", "Fin"]
}
2. JSON接口
近年来,互联网上出现了很多卓越的JSON格式的API (Application Programming Interface,应用编程接口)。
借助这些API,应用程序可以从作为数据交换平台的互联网上,获得海量的有关任何主题的数据。
API令应用开发者无须连接到数据库,就能请求并使用各种形式的数据资源。
- 例如下面的JSON数据来自Dark Sky天气预报服务系统,通过json格式字符串描述了经纬度、时区、温度等内容。
- {"latitude": 42.3601, "longitude": -71.0589, "timezone": "America/New_York",
- "currently": {"time": 1509993277, "summary": "Drizzle", "icon": "rain",
- "nearestStormDistance": 0, "precipIntensity": 0.0089, ...},
- "minutely": {"summary": "Light rain stopping in 13 min., starting again 30 min. later.",
- "icon": "rain", "data": [{...}, ...]},
- "hourly": {"summary": ... }, ... }
3. 在Go语言中使用JSON
Go语言标准库通过encoding/json包提供对JSON数据的编码和解码操作。
JSON编码,即将Go语言数据类型的变量转换为JSON格式的字符串
- 定义结构体类型
- type Person struct { ... },结构体的字段名对应json的“键”
- 创建结构体变量
- p := Person{ ... }
- 将结构体变量编码为JSON格式的字节切片
- jb, err := json.Marshal(p)
- 将JSON格式的字节切片转换为JSON格式的字符串
- js := string(jb)
// 创建结构体
// 结构体可将多个不同类型的数据组织在一起,是一种绝佳的数据封装形式
package main
import "fmt"
type person struct {
name string
age int
hobbies []string
}
func main() {
p := person{
name: "George",
age: 40,
hobbies: []string{"Cycling", "Cheese", "Techno"},
}
fmt.Printf("%+v\n", p)
}
// 打印输出:
{name:George age:40 hobbies:[Cycling Cheese Techno]}
// 将结构体编码为JSON字符串
// json.Marshal string
// 结构体 -------------> JSON字节切片 ------> JSON字符串
package main
import (
"encoding/json"
"fmt"
"log"
)
// Person with name, age and hobbies
type Person struct {
Name string
Age int
Hobbies []string
}
func main() {
p := Person{
Name: "George",
Age: 40,
Hobbies: []string{
"Cycling", "Cheese", "Techno"},
}
fmt.Printf("%+v\n", p)
jb, err := json.Marshal(p) //将结构体变量编码为JSON格式的字节切片
if err != nil {
log.Fatal(err)
}
js := string(jb) // 将json字节切片转换为json字符串
fmt.Println(js)
}
// 打印输出:
{Name:George Age:40 Hobbies:[Cycling Cheese Techno]}
{"Name":"George","Age":40,"Hobbies":["Cycling","Cheese","Techno"]}
默认情况下,JSON字符串中的键和值分别取自结构体中的字段名和字段值(大小写敏感)。
- type Person struct {
- Name string
- Age int
- Hobbies []string
- }
- {"Name":"George","Age":40,"Hobbies":["Cycling","Cheese","Techno"]}
如果为结构体字段指定了JSON标签,则以标签文本作为JSON字符串的键。
- type Person struct {
// 标签是以反引号包围的
Name string `json:"name"`
Age int `json:"age"`
Hobbies []string `json:"hobbies"`
}
{"name":"George","age":40,"hobbies":["Cycling","Cheese","Techno"]}
// 使用JSON标签
// 默认情况下,JSON字符串中的键和值分别取自结构体中的字段名和字段值,但
// 如果为结构体中的字段指定了JSON标签,则以标签文本作为JSON字符串的键
//
// type 结构体 struct {
// 字段1 类型1 `json:"键1"`
// 字段2 类型2 `json:"键2"`
// ...
// 字段n 类型n `json:"键n"`
// }
package main
import (
"encoding/json"
"fmt"
"log"
)
// Person with name, age and hobbies
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
Hobbies []string `json:"hobbies"`
}
func main() {
p := Person{
Name: "George",
Age: 40,
Hobbies: []string{
"Cycling", "Cheese", "Techno"},
}
fmt.Printf("%+v\n", p)
jb, err := json.Marshal(p)
if err != nil {
log.Fatal(err)
}
js := string(jb)
fmt.Println(js)
}
// 打印输出:
{Name:George Age:40 Hobbies:[Cycling Cheese Techno]}
{"name":"George","age":40,"hobbies":["Cycling","Cheese","Techno"]}
默认情况下,结构体中的零值字段也会被编码到JSON字符串中。
- type Person struct {
- Name string `json:"name"`
- Age int `json:"age"`
- Hobbies []string `json:"hobbies"`
- }
p:= Person{} // 使用默认零值初始化
-
- 通过json.Marshal(p)函数将结构体解析为json字符如下:
{"name":"","age":0,"hobbies":[]}
在JSON标签中使用"omitempty"关键字,令编码器在编码时忽略零值字段。
- type Person struct {
- Name string `json:"name,omitempty"`
- Age int `json:"age,omitempty"`
- Hobbies []string `json:"hobbies,omitempty"`
- }
- {}
// 忽略空字段
// 默认情况下,结构体中的零值字段也会被编码到JSON字符串中,除非在其JSON
// 标签中使用了"omitempty"关键字,指示编码器在编码的过程中忽略零值字段
package main
import (
"encoding/json"
"fmt"
"log"
)
// Person with name, age and hobbies
type Person struct {
Name string `json:"name,omitempty"`
Age int `json:"age,omitempty"`
Hobbies []string `json:"hobbies,omitempty"`
}
func main() {
p := Person{}
fmt.Printf("%+v\n", p)
jb, err := json.Marshal(p)
if err != nil {
log.Fatal(err)
}
js := string(jb)
fmt.Println(js)
}
// 打印输出:
{Name: Age:0 Hobbies:[]}
{}