Goencode/jsonJSON
JSON
json
解析简单JSON
JSONnamecreatedidfruit
{
"name": "Standard",
"fruit": [
"Apple",
"Banana",
"Orange"
],
"id": 999,
"created": "2018-04-09T23:00:00Z"
}
Go
type FruitBasket struct {
Name string `json:"name"`
Fruit []string `json:"fruit"`
Id int64 `json:"id"`
Created time.Time `json:"created"`
}
JSON
package main
import (
"fmt"
"encoding/json"
"time"
)
func main() {
type FruitBasket struct {
Name string `json:"name"`
Fruit []string `json:"fruit"`
Id int64 `json:"id"`
Created time.Time `json:"created"`
}
jsonData := []byte(`
{
"name": "Standard",
"fruit": [
"Apple",
"Banana",
"Orange"
],
"id": 999,
"created": "2018-04-09T23:00:00Z"
}`)
var basket FruitBasket
err := json.Unmarshal(jsonData, &basket)
if err != nil {
fmt.Println(err)
}
fmt.Println(basket.Name, basket.Fruit, basket.Id)
fmt.Println(basket.Created)
}
输出
Standard [Apple Banana Orange] 999
2018-04-09 23:00:00 +0000 UTC
json.UnMarshal()c := []byte(s)
解析内嵌对象的JSON
fruit"fruit" : {"name":"Apple", "priceTag":"$1"}
jsonData := []byte(`
{
"name": "Standard",
"fruit" : {"name": "Apple", "priceTag": "$1"},
"def": 999,
"created": "2018-04-09T23:00:00Z"
}`)
Go
type Fruit struct {
Name string `json":name"`
PriceTag string `json:"priceTag"`
}
type FruitBasket struct {
Name string `json:"name"`
Fruit Fruit `json:"fruit"`
Id int64 `json:"id"`
Created time.Time `json:"created"`
}
解析内嵌对象数组的JSON
JSONFruit
"fruit" : [
{
"name": "Apple",
"priceTag": "$1"
},
{
"name": "Pear",
"priceTag": "$1.5"
}
]
Fruit[]Fruit
type Fruit struct {
Name string `json:"name"`
PriceTag string `json:"priceTag"`
}
type FruitBasket struct {
Name string `json:"name"`
Fruit []Fruit `json:"fruit"`
Id int64 `json:"id"`
Created time.Time `json:"created"`
}
解析具有动态Key的
FruitId
"Fruit" : {
"1": {
"Name": "Apple",
"PriceTag": "$1"
},
"2": {
"Name": "Pear",
"PriceTag": "$1.5"
}
}
KeyFruitKeystringFruitmap
type Fruit struct {
Name string `json:"name"`
PriceTag string `json:"priceTag"`
}
type FruitBasket struct {
Name string `json:"name"`
Fruit map[string]Fruit `json:"fruit"`
Id int64 `json:"id"`
Created time.Time `json:"created"`
}
运行下面完整的代码
package main
import (
"encoding/json"
"fmt"
"time"
)
func main() {
type Fruit struct {
Name string `json:"name"`
PriceTag string `json:"priceTag"`
}
type FruitBasket struct {
Name string `json:"name"`
Fruit map[string]Fruit `json:"fruit"`
Id int64 `json:"id"`
Created time.Time `json:"created"`
}
jsonData := []byte(`
{
"Name": "Standard",
"Fruit" : {
"1": {
"name": "Apple",
"priceTag": "$1"
},
"2": {
"name": "Pear",
"priceTag": "$1.5"
}
},
"id": 999,
"created": "2018-04-09T23:00:00Z"
}`)
var basket FruitBasket
err := json.Unmarshal(jsonData, &basket)
if err != nil {
fmt.Println(err)
}
for _, item := range basket.Fruit {
fmt.Println(item.Name, item.PriceTag)
}
}
输出
Apple $1
Pear $1.5
解析包含任意层级的数组和对象的JSON数据
JSONencoding/json
map[string]interface{}JSON[]interface
json.Unmarshlinterface{}
jsonData := []byte(`{"Name":"Eve","Age":6,"Parents":["Alice","Bob"]}`)
var v interface{}
json.Unmarshal(jsonData, &v)
data := v.(map[string]interface{})
for k, v := range data {
switch v := v.(type) {
case string:
fmt.Println(k, v, "(string)")
case float64:
fmt.Println(k, v, "(float64)")
case []interface{}:
fmt.Println(k, "(array):")
for i, u := range v {
fmt.Println(" ", i, u)
}
default:
fmt.Println(k, v, "(unknown)")
}
}
JSONJSONfloatJSONJSONJSON
用 Decoder解析数据流
UnMarshallJSONJSONHTTPio.ReaderJSONencode/jsonUnMarshallDecodeJSON
package main
import (
"encoding/json"
"fmt"
"io"
"log"
"strings"
)
func main() {
const jsonStream = `
{"Name": "Ed", "Text": "Knock knock."}
{"Name": "Sam", "Text": "Who's there?"}
{"Name": "Ed", "Text": "Go fmt."}
{"Name": "Sam", "Text": "Go fmt who?"}
{"Name": "Ed", "Text": "Go fmt yourself!"}
`
type Message struct {
Name, Text string
}
dec := json.NewDecoder(strings.NewReader(jsonStream))
for {
var m Message
if err := dec.Decode(&m); err == io.EOF {
break
} else if err != nil {
log.Fatal(err)
}
fmt.Printf("%s: %s\n", m.Name, m.Text)
}
}
输出
Ed: Knock knock.
Sam: Who's there?
Ed: Go fmt.
Sam: Go fmt who?
Ed: Go fmt yourself!
JSON 编码需要注意的几个点
自定义JSON键名
只有选择用大写字母开头的字段名称,导出的结构体成员才会被编码。
JSONkeyJSON key
type Fruit struct {
Name string `json:"nick_name"`
PriceTag string `json:"price_level_tag"`
}
编码JSON时忽略掉指定字段
JSONJSON
JSONIdCardJSON
type User struct {
Name string `json:"name"`
Age int `json:"int"`
IdCard string `json:"-"`
}
encoding/jsonJSON
// 忽略字段
Field int `json:"-"`
// 自定义key
Field int `json:"myName"`
// 数据为空时忽略字段
Field int `json:"myName,omitempty"`
omitemptyJSON
解决空切片在JSON里被编码成null
jsonomitemptynull[]
nilvarf[]intsliceJSONnullJSON slice[]slice
运行下面的例子可以看出两点的区别:
package main
import (
"encoding/json"
"fmt"
)
type Person struct {
Friends []string
}
func main() {
var f1 []string
f2 := make([]string, 0)
json1, _ := json.Marshal(Person{f1})
json2, _ := json.Marshal(Person{f2})
fmt.Printf("%s\n", json1)
fmt.Printf("%s\n", json2)
}
输出
{"Friends":null}
{"Friends":[]}
Goappendnil