GO Json
1、解析时,结构体的Tag使用
tag就是标签,给结构体的每个字段打上一个标签,标签冒号前是类型,后面是标签名;
- json解析时用 json,同时注意bson,bson用于mongdb的存储解析
- omitempty,可以在序列化的时候忽略0值或者空值
- type,在序列化或者反序列化的时候,可能结构体类型和需要的类型不一致,这个时候可以指定类型,支持string,number和boolean
1 package main 2 3 import ( 4 "encoding/json" 5 "fmt" 6 ) 7 8 9 type Product struct { 10 Name string `json:"name"` 11 ProductID int64 `json:"-"` // 该字段不进行序列化 12 Number int `json:"number"` 13 Price float64 `json:"price,omitempty"` //忽略0值或空值 14 IsOnSale bool `json:"is_on_sale,string"` //设置转化的type 支持string,number和boolean 15 } 16 17 18 func main() { 19 20 21 var data = `{"name":"Xiao mi","product_id":"10","number":10000,"price":0,"is_on_sale":"true"}` 22 p := &Product{} 23 err := json.Unmarshal([]byte(data), p) 24 fmt.Println(err) 25 fmt.Println(*p) 26 Serialization,_ := json.Marshal(p) 27 fmt.Println(string(Serialization)) 28 29 }
2、自定义解析,常用于定制化校验
- gin 框架中,ShouBindJson也有类似功能,可直接定义tag,或自定义解析
1 package main 2 3 import ( 4 "encoding/json" 5 "errors" 6 "fmt" 7 ) 8 9 type Marshaler interface { 10 MarshalJSON() ([]byte, error) 11 } 12 type Unmarshaler interface { 13 UnmarshalJSON() ([]byte, error) 14 } 15 16 //实现以上接口,接口的方法只是对结构体字段的值做处理。 17 // 在序列化与反序列化时json.Marshal和json.Unmarshal,会先调用你自定义的实现对应接口的方法, 18 //可以理解为一道拦截逻辑,即在序列化和反序列化前增加的额外逻辑 19 20 type Phone struct { 21 Number string 22 } 23 24 25 func (p Phone) MarshalJSON() ([]byte, error) { 26 //检查 27 if len(p.Number) != 11 { 28 return nil,errors.New("not fit rule") 29 } 30 for _,v := range p.Number { 31 if v > '9' || v < '0'{ 32 return nil,errors.New("Contains non-digits") 33 } 34 } 35 //注意只是对字段值处理 36 return json.Marshal(p.Number) 37 } 38 39 40 41 func main() { 42 phone := Phone{"1980987578"} 43 phoneJsson,err := json.Marshal(phone) 44 fmt.Println(string(phoneJsson),err) 45 }
输出:
json: error calling MarshalJSON for type *main.Phone: not fit rule