解析JSON
- 结构体中的小写字段非导出,不会被encode或decode
- Use json.Decoder if your data is coming from an io.Reader stream, or you need to decode multiple values from a stream of data
- For the case of reading from an HTTP request, I’d pick json.Decoder since you’re obviously reading from a stream.
- Use json.Unmarshal if you already have the JSON data in memory.
Unmarshal
func Unmarshal(data []byte, v interface{}) error
// 使用方法
var s string
var m ConfigStrcut
// 字符串转结构体
err := json.Unmarshal([]byte(s), &m)
- v一般是一个指针
- 能够被赋值的字段必须是可导出字段(即首字母大写)
- 当你接收到一个很大的JSON数据结构而你却只想获取其中的部分数据的时候,你只需将你想要的数据对应的字段名大写
- 如果不知道JSON数据的结构,可以先解析到空接口中,然后利用断言解析
Decoder
// NewDecoder returns a new decoder that reads from r.
func NewDecoder(r io.Reader) *Decoder
// Decode reads JSON-encoded value from input and stores it in the value pointed to by v.
func (dec *Decoder) Decode(v interface{}) error
// 使用方式
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
}
//初始化一个Decoder对象
//func NewDecoder(r io.Reader) *Decoder
dec := json.NewDecoder(strings.NewReader(jsonStream))
for {
var m Message
//创建的decoder对象的Decide方法可以将内容解析到接口v中
//func (dec *Decoder) Decode(v interface{}) error
//读取到末尾和读取错误
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)
}
生成JSON
- JSON 对象只支持字符串类型的 key;要编码一个map,该map必须是
map[string]T
类型
Marshal
func Marshal(v interface{}) ([]byte, error)
// 使用方法
// 结构体转[]byte
var m ConfigStruct
str, err := json.Marshal(m)
Encoder
// NewEncoder returns a new encoder that writes to w.
func NewEncoder(w io.Writer) *Encoder
//Encode writes the JSON encoding of v to the stream.
func (enc *Encoder) Encode(v interface{}) error
// 使用方法
// 结构体转为[]byte
m := struct {
Name, Text string
}{
Name: "Ed", Text: "Knock knock.",
}
var s bytes.Buffer
err := json.NewEncoder(&s).Encode(m)
str := s.Bytes()
json-iterator
- 滴滴开源的json解析器,速度比原生的快很多
// 兼容标准方式的写法
import jsoniter "github.com/json-iterator/go"
var json = jsoniter.ConfigCompatibleWithStandardLibrary
func f() {
json.Marshal(...)
json.Unarshal(...,...)
}
Struct Tag
- 字段tag
- 字段的tag是
"-"
,那么这个字段不会输出到JSON - tag中如果带有
"omitempty"
选项,那么如果该字段值为空,就不会输出到JSON串中 - 如果字段类型是bool, string, int, int64等,而tag中带有
",string"
选项,那么这个字段在输出到JSON的时候会把该字段对应的值转换成JSON字符串
- 字段的tag是
- JSON对象只支持string作为key,所以要编码一个map,那么必须是
map[string]T
这种类型
type Server struct {
// ID 不会导出到JSON中
ID int `json:"-"`
ServerName string `json:"serverName"`
// code在json中的类型会变成string
code int `json:"code,string"`
// 如果 ServerIP 为空,则不输出到JSON串中
ServerIP string `json:"serverIP,omitempty"`
}
参考
Golang处理json(一)— 编码
Golang处理json(二)— 解码