zoukankan      html  css  js  c++  java
  • golang-Json编码解码

    在线工具:https://www.json.cn

    一. 类型映射

    • golang和json的数据类型不一致,在编码或解码的过程中必然需要做类型映射。

    1.从golang到json:

    golang json
    bool Boolean
    int、float等数字 Number
    string String
    []byte(base64编码) String
    struct Object,再递归打包
    array/slice Array
    map Object
    interface{} 按实际类型转换
    nil null
    channel,func UnsupportedTypeError

    2.从json到golang:

    json golang
    Boolean bool
    Number float64
    String string
    Array []interface{}
    Object map[string]interface{}
    null nil

    二. 输出控制

    • 第一个标签为别名,后面控制标签可叠加。
    • 编码或解码的中间数据状态为字节数组
    type User struct {
       Name string `json:"user_name"` //修改别名
       Age uint8 `json:",string"` //修改类型
       Addr string `json:"-"` //忽略字段
       Vip bool `json:",omitempty"` //排除缺省值
       Asset int64 `json:"amount,string,omitempty"` //标签叠加
       Skill []string `json:"skill"` //复杂类型
    }
    
    func main() {
       obj :=User{Name:"tom",Age:18,Addr:"BJ",Vip:false,Asset:888,Skill:[]string{"golang","python"}}
       bts, _ := json.MarshalIndent(obj,"","	") //缩进
       fmt.Println(string(bts))
    }
    

    三. 类型编码

    1.结构体/结构体指针: 映射为Object

    func main() {
       obj := struct {A string;B int64}{"a", 1}
       bts, _ := json.Marshal(obj) //结构体
       fmt.Println(string(bts))
    
       ptr := &obj //结构体指针
       bts, _ = json.Marshal(ptr)
       fmt.Println(string(bts))
    }
    

    2.数组/切片: 映射为Array

    func main() {
       arr := []string{"a","b","c"}
       bts, _ := json.Marshal(arr) 
       fmt.Println(string(bts))
    }
    

    3.字典: 映射为Object

    func main() {
       mp := map[int]string{1:"a",2:"b",3:"c"}
       bts, _ := json.Marshal(mp)
       fmt.Println(string(bts))
    }
    

    四. 类型解码

    1.对象解码

    func main() {
       str := `{"A":"a","B":1}`
       obj := new(struct {A string;B int64})
       _ = json.Unmarshal([]byte(str), &obj )
       fmt.Println(obj)
    }
    

    2.数组解码

    func main() {
       arr := `["a","b","c"]`
    
       slise:=make([]string,0)
       _ = json.Unmarshal([]byte(arr),&slise)
       fmt.Println(slise)
    }
    

    3.字典解码

    func main() {
       str := `{"1":"a","2":"b","3":"c"}`
    
       mp := make(map[int]string)
       _ = json.Unmarshal([]byte(str), &mp)
       fmt.Println(mp)
    }
    

    五. 输出重写

    • Marshal函数将会递归遍历整个对象,并根据类型数据的MarshalJSON方法打印输出格式。
    //自定义的Json时间格式
    type Jtime time.Time
    
    //实现了encoding/json/encode.go的Marshaler接口
    func (p Jtime) MarshalJSON() ([]byte, error) {
       var stamp = fmt.Sprintf("%d", time.Time(p).Unix())
       //var stamp = fmt.Sprintf(""%s"", time.Time(p).Format("2006-01-02 15:04:05"))
       return []byte(stamp), nil
    }
    
    func main() {
       obj := struct {
          Name string `json:"nick_name"`
          Date Jtime `json:"create_at"`
       }{"Jack", Jtime(time.Date(2018, 1, 1, 00, 00, 00, 00, time.Local))}
    
       //编码
       bts, _ := json.MarshalIndent(obj, "", "	")
       fmt.Println(string(bts))
    
       //解码
       _ = json.Unmarshal(bts, obj)
       fmt.Printf("%s %q", obj.Name, time.Time(obj.Date))
    }
    

    六. 扩展功能

    1. Json格式验证:json.Valid()

    func main() {
       str := `{"nick_name":"Lucy","user_age":28}` //Object
       str = `["a","b"]` //Array
       ok := json.Valid([]byte(str))
       fmt.Println(ok)
    }
    

    2. 自定义编码器:json.NewEncoder()

    func main() {
       obj := struct {
          Name string `json:"nick_name"`
          Age uint `json:"user_age"`
       }{"Lucy", 28}
    
       outer, _ := os.Create("json.txt") //文件输出
       outer = os.Stdout //标准输出
       encoder := json.NewEncoder(outer)
       encoder.SetIndent("", "	")
       encoder.Encode(obj)
    }
    

    3. 缩进处理:json.Indent(),对已编码对字节数组进行缩进

    func main() {
       obj := struct {Name string;Age uint}{"Lucy", 28}
       bts, _ := json.Marshal(obj)
       
       var buf bytes.Buffer
       _=json.Indent(&buf,bts,"","	")
       buf.WriteTo(os.Stdout)
    }
    

    4. Json字符串压缩:json.Compact()

    func main() {
       str := `
    {
       "nick_name": "Lucy",
       "user_age": 28
    }`
    
       var buf bytes.Buffer
       _ = json.Compact(&buf, []byte(str)) //压缩
       buf.WriteTo(os.Stdout)
    }
    

    5. Html编码处理:json.HTMLEscape()

    func main() {
       str := `{"content": "<a src="http://www.xxx.com">Link</a>"}`
       var buf bytes.Buffer
       json.HTMLEscape(&buf, []byte(str)) 
       buf.WriteTo(os.Stdout)
    }
    

    6. 二次解码:json.RawMessage,根据json数据包的某个标识,分别解码成不同类型的对象。

    type Student struct {
       Sno string //学号
       Name string //姓名
       Major string //专业
    }
    
    type Teacher struct {
       Name string //姓名
       Subject string //学科
    }
    
    // 任何对象都能装的数据容器,具体类型根据Type字段区分
    type JsonObject struct {
       Type int //对象类型
       Obj interface{} //对象数据
    }
    
    func main() {
       user := `{"Type":1,"Obj":{"Sno":"S001","Name":"Tom","Major":"computer"}}` //Student
       user = `{"Type":2,"Obj":{"Name":"Bob","Subject":"quantum mechanics"}}` //Teacher
    
       var obj json.RawMessage
       pkg := JsonObject{Obj: &obj}
    
       //第一次解码: 先解码外部包装数据对象,获取类型依据
       if err := json.Unmarshal([]byte(user), &pkg); err != nil {
          panic(err)
       }
    
       //第二次解码: 根据第一次的解码结果,再次对内部对象Obj进行解码
       switch pkg.Type {
       case 1:
          var stu = Student{}
          _ = json.Unmarshal(obj, &stu)
          fmt.Println(stu)
       case 2:
          var tch = Teacher{}
          _ = json.Unmarshal(obj, &tch)
          fmt.Println(tch)
       }
    }
    

    七. Bson编码

    • Bson基于json格式,是mongoDB的数据存储格式。
    • 1.速度快:json以字符串形式存储,需要文件扫描,结构匹配。bson是按结构存储,可以精准定位,高效读写。
    • 2.操作简单:json无数据类型,是基于字符的操作,面临很大的操作开销。bson可以指定数据类型。
    • 3.字节数组:二进制的存储不再需要先base64转换后再存成json,大大减少了计算开销和数据大小。
    import "gopkg.in/mgo.v2/bson"
    type Person struct {
       Name string `bson:"nick_name"`
       Age int32 `bson:"-"`
       Phone string `bson:",omitempty"`
    }
    func main() {
       p := &Person{"Bob", 18, ""}
    
       bytes, _ := bson.Marshal(p) //Bson编码
       fmt.Printf("%q
    ", bytes)
    
       um := &Person{}
       bson.Unmarshal(bytes, &um) //strust解码
       fmt.Println(um)
    
       mp := bson.M{}
       bson.Unmarshal(bytes, mp) //map解码
       fmt.Println(mp)
    }
    

    参考:
    http://www.cnblogs.com/chuanheng/p/go_bson_struct.html
    http://blog.csdn.net/tiaotiaoyly/article/details/38942311
    https://studygolang.com/articles/2552
    http://labix.org/gobson
    http://blog.csdn.net/hengyunabc/article/details/6897540
    https://godoc.org/gopkg.in/mgo.v2/bson

  • 相关阅读:
    .NET XmlNavigator with Namespace
    编程要素
    【FOJ】1962 新击鼓传花游戏
    【POJ】1389 Area of Simple Polygons
    【POJ】2482 Stars in Your Window
    【HDU】3265 Posters
    【HDU】1199 Color the Ball
    【HDU】3642 Get The Treasury
    【HDU】4027 Can you answer these queries?
    【HDU】1542 Atlantis
  • 原文地址:https://www.cnblogs.com/Hollson/p/11248460.html
Copyright © 2011-2022 走看看