1 json介绍
JSON (JavaScript Object Notation)是一种比XML更轻量级的数据交换格式,在易于人们阅读和编写的同时,也易于程序解析和生成。尽管JSON是JavaScript的一个子集,但JSON采用完全独立于编程语言的文本格式,且表现为键/值对集合的文本描述形式(类似一些编程语言中的字典结构),这使它成为较为理想的、跨平台、跨语言的数据交换语言。
例如:
{
"company": "itcast",
"subjects": [
"Go",
"C++",
"Python",
"Test"
],
"isok": true,
"price": 666.666
}
开发者可以用 JSON 传输简单的字符串、数字、布尔值,也可以传输一个数组,或者一个更复杂的复合结构。在 Web 开发领域中, JSON被广泛应用于 Web 服务端程序和客户端之间的数据通信。
Go语言内建对JSON的支持。使用Go语言内置的encoding/json 标准库,开发者可以轻松使用Go程序生成和解析JSON格式的数据。
JSON官方网站:http://www.json.org/。
在线格式化:http://www.json.cn/。
2 根据结构体生成json
package main
import (
"encoding/json"
"fmt"
)
//成员变量名首字母必须大写
type IT struct {
Company string
Subjects []string
IsOk bool
Price float64
}
func main() {
// 1. 定义一个结构体变量,同时初始化
s := IT{"itcast", []string{"Go", "C++", "Python", "Test"}, true, 666.666}
// 2. 编码,根据内容生成json文本
//buf, err := json.Marshal(s) // 没有对应的换行符
buf, err := json.MarshalIndent(s, "", " ")// 或者使用这种格式化生成,会有对应的换行符
if err != nil {
fmt.Println("err = ", err)
return
}
fmt.Println("buf = ", string(buf))
}
3 struct_tag的使用
在上面的例子看到,我们根据结构体生成的json的key都是大写的,因为结构体名字在go语言中不大写的话,又没有访问权限,这种问题会影响到我们对json的key的名字,所以go官方给出了struct_tag的方法去修改生成json时,对应key的名字。
package main
import (
"encoding/json"
"fmt"
)
//成员变量名首字母必须大写
type IT struct {
//Company string `json:"-"` //此字段不会输出到屏幕
// ''单引号后面是struct,代表二次编码,可以把生成的json的key从大写变成小写
Company string `json:"company"`
Subjects []string `json:"subjects"`
IsOk bool `json:"isok"`
//IsOk bool `json:"string"`//转成字符串再输出编码
Price float64 `json:"price"`
}
func main() {
// 1. 定义一个结构体变量,同时初始化
s := IT{"itcast", []string{"Go", "C++", "Python", "Test"}, true, 666.666}
// 2. 编码,根据内容生成json文本
buf, err := json.MarshalIndent(s, "", " ") //格式化编码
if err != nil {
fmt.Println("err = ", err)
return
}
fmt.Println("buf = ", string(buf))
}
4 通过map生成json
package main
import (
"encoding/json"
"fmt"
)
func main() {
// 1. 创建一个map,注意value是万能指针类型
m := make(map[string]interface{}, 4)
m["company"] = "itcast"
m["subjects"] = []string{"Go", "C++", "Python", "Test"}
m["isok"] = true
m["price"] = 666.666
// 2. 编码成json
//result, err := json.Marshal(m)
result, err := json.MarshalIndent(m, "", " ")
if err != nil {
fmt.Println("err = ", err)
return
}
fmt.Println("result = ", string(result))
}
5 json解析到结构体
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() {
jsonBuf := `
{
"company": "itcast",
"subjects": [
"Go",
"C++",
"Python",
"Test"
],
"isok": true,
"price": 666.666
}`
// 一 获取json全部的内容
// 1. 定义一个结构体变量
var tmp IT
// 2. 第二个参数要地址传递,否则无法修改变量的值
err := json.Unmarshal([]byte(jsonBuf), &tmp)
if err != nil {
fmt.Println("err = ", err)
return
}
//fmt.Println("tmp = ", tmp)
fmt.Printf("tmp = %+v\n", tmp)
// 二 获取json指定的内容
type IT2 struct {
Subjects []string `json:"subjects"` //二次编码
}
var tmp2 IT2
err = json.Unmarshal([]byte(jsonBuf), &tmp2) //第二个参数要地址传递
if err != nil {
fmt.Println("err = ", err)
return
}
fmt.Printf("tmp2 = %+v\n", tmp2)
}
6 json解析到map
package main
import (
"encoding/json"
"fmt"
)
func main() {
jsonBuf := `
{
"company": "itcast",
"subjects": [
"Go",
"C++",
"Python",
"Test"
],
"isok": true,
"price": 666.666
}`
// 1. 创建一个map
m := make(map[string]interface{}, 4)
// 2. 第二个参数要地址传递
err := json.Unmarshal([]byte(jsonBuf), &m)
if err != nil {
fmt.Println("err = ", err)
return
}
fmt.Printf("m = %+v\n", m)
//var str string
//str = string(m["company"])// err,无法转换,
//str = m["company"].(string)// ok.或者通过类型断言取map的内容。
//fmt.Printf("str = %s\n", str)
// 3. 类型断言, 值,它是value类型
var str string
for key, value := range m {
//fmt.Printf("%v ============> %v\n", key, value)
switch data := value.(type) {
case string:
str = data
fmt.Printf("map[%s]的值类型为string, value = %s\n", key, str)
case bool:
fmt.Printf("map[%s]的值类型为bool, value = %v\n", key, data)
case float64:
fmt.Printf("map[%s]的值类型为float64, value = %f\n", key, data)
case []string:
fmt.Printf("map[%s]的值类型为[]string, value = %v\n", key, data)
case []interface{}:
fmt.Printf("map[%s]的值类型为[]interface, value = %v\n", key, data)
}
}
}