go笔记:json的简单处理

简单处理

json的本质就是数组和字典的组合,但系统的数组和字典都是确定类型的,所以,go的interface{}就能大显身手了。
下面的代码描述了自定义类型 ListDict。有了这两个工具,处理json就非常的方便。

package main

import (
    "encoding/json"
    "fmt"
)

type List []interface{}

func ToList(obj interface{}) List {
    switch obj := obj.(type) {
    case []interface{}:
        return obj
    case string:
        var f interface{}
        err := json.Unmarshal([]byte(obj), &f)
        if err != nil {
            panic("ToList err" + err.Error())
        }
        return f.([]interface{})
    }

    panic("ToList failed, input type not in ([]interface{}, string)")
}

func (l *List) String() string {
    result, err := json.Marshal(l)
    if err != nil {
        panic("json to string error" + err.Error())
    }
    return string(result)
}

type Dict map[string]interface{}

func ToDict(obj interface{}) Dict {
    switch obj := obj.(type) {
    case map[string]interface{}:
        return obj
    case string:
        var f interface{}
        err := json.Unmarshal([]byte(obj), &f)
        if err != nil {
            panic("ToDict err" + err.Error())
        }
        return f.(map[string]interface{})
    }
    panic("ToDict failed, input type not in (map[string]interface{}, string)")
}

func (d *Dict) String() string {
    result, err := json.Marshal(d)
    if err != nil {
        panic("json to string error" + err.Error())
    }
    return string(result)
}

func main() {
    // test Dict
    objmap := make(map[string]interface{})
    objmap["name"] = "yzh"
    objmap["age"] = 28

    objdict := ToDict(objmap)
    fmt.Println(objdict.String())

    objdict["age"] = 18
    fmt.Println(objdict.String())

    dictstr := `{"age":28,"name":"yzh"}`
    objdict = ToDict(dictstr)
    objdict["age"] = 16
    fmt.Println(objdict.String())

    // test List
    objarray := make([]interface{}, 0)
    objarray = append(objarray, "haha")

    objlist := ToList(objarray)
    objlist = append(objlist, objdict)
    objlist[0] = "haha2"
    fmt.Println(objlist.String())

    objlist = ToList(`["haha2",{"age":16,"name":"yzh"}]`)
    objlist[0] = "haha3"
    fmt.Println(objlist.String())
}

封装一下

简简单单写了一个函数,用来处理json。终于不用定义一大堆结构体了。

/*
    myJson是对json的封装,用interface{} 屏蔽了对结构体的使用依赖。常见操作如下:
    type TestStruct struct {
        ID   int
        Name string
    }

    func TestJson() {
        jsonStr := []byte("{\"hi\":\"hello\",\"myarr\":[{\"my\":\"zhh\"}]}")
        jsonObj := myJson.NewFromBytes(jsonStr)
        appendStr := []byte("{\"you\":\"dazhu\"}")
        appendObj := myJson.NewFromBytes(appendStr)

        logger.Info("%s", jsonStr)
        // 获取相应值,并设置值
        if jsonObj.Get("hi").String() != "null" {
            jsonObj.Set("hi", "haha")
        }

        // 获取一个slice中的对应值,并设置它
        jsonObj.Get("myarr").Index(0).Set("my", "zhhdazhu")

        // 在slice中添加新的元素
        jsonObj.AppendKey("myarr", appendObj)

        // 判定一个值是否存在
        if jsonObj.Get("haha123").String() == "null" {
            logger.Info("haha123 not exist")
        }

        // 将myjson对象转为json字符串
        testObj := jsonObj.String()
        logger.Info(testObj)

        // 从结构体创建myJson对象
        stcObj := TestStruct{ID: 1, Name: "yzh"}
        jsonObj2 := myJson.NewFromStruct(stcObj)
        logger.Info("%s", jsonObj2.String())
    }
*/
package common

import (
    "encoding/json"
    "fmt"
)

type MyJson struct {
    prev      *MyJson
    prevkey   string
    previndex int
    data      interface{}
}

// NewJson 从其它对象创建myJson对象。
func NewJson(data interface{}) *MyJson {
    switch v := data.(type) {
    case string:
        return NewJsonFromStr(v)
    case []byte:
        return NewJsonFromBytes(v)
    default:
        return NewJsonFromData(v)
    }
}

// NewJsonFromBytes 从bytes对象创建myJson对象。bytes对象必须是标准的json格式。
func NewJsonFromBytes(b []byte) *MyJson {
    var f interface{}
    err := json.Unmarshal(b, &f)
    if err != nil {
        panic("NewMyJson err" + err.Error())
    }

    return &MyJson{data: f}
}

// NewJsonFromStr 从一个字符串对象创建myJson对象
func NewJsonFromStr(str string) *MyJson {
    var f interface{}
    err := json.Unmarshal([]byte(str), &f)
    if err != nil {
        errstr := fmt.Sprintf("js解析失败:%v", str)
        return NewErrJson(1, errstr)
    }

    return &MyJson{data: f}
}

func NewErrJson(errcode int, errmsg string) *MyJson {
    result := NewJsonFromStr("{}")
    result.Set("err_msg", errmsg)
    result.Set("err", errcode)

    return result
}

// NewJsonFromStruct 从一个结构体对象创建myJson对象
func NewJsonFromStruct(b interface{}) *MyJson {
    var f interface{}
    bytesArr, err := json.Marshal(b)
    if err != nil {
        panic("NewMyJson Marshal err" + err.Error())
    }

    err = json.Unmarshal(bytesArr, &f)
    if err != nil {
        panic("NewMyJson Unmarshal err" + err.Error())
    }

    return &MyJson{data: f}
}

func NewJsonFromData(d interface{}) *MyJson {
    return &MyJson{data: d}
}

// Get 获取一个key值。
func (j *MyJson) Get(key string) *MyJson {
    m, ok := j.data.(map[string]interface{})
    if !ok {
        return &MyJson{
            prev:    j,
            prevkey: key,
            data:    nil,
        }
    }

    v := m[key]

    return &MyJson{
        prev:    j,
        prevkey: key,
        data:    v,
    }
}

func maintRelation(child *MyJson) {
    if child.prev == nil {
        return
    }

    switch child.prev.Value().(type) {
    case map[string]interface{}:
        child.prev.Set(child.prevkey, child)
    case []interface{}:
        child.prev.Set(child.previndex, child)
    }
}

// Append 往数组中添加值
func (j *MyJson) Append(val interface{}) *MyJson {
    if value, ok := val.(*MyJson); ok {
        j.data = append(j.data.([]interface{}), value.Value())
    } else {
        j.data = append(j.data.([]interface{}), val)
    }
    maintRelation(j)
    return j
}

// Insert 往数组中添加值
func (j *MyJson) Insert(index int, val interface{}) *MyJson {
    v := j.data.([]interface{})
    if value, ok := val.(*MyJson); ok {
        rear := append([]interface{}{}, v[index:]...)
        v := append(v[0:index], value.Value())
        j.data = append(v, rear...)
    } else {
        rear := append([]interface{}{}, v[index:]...)
        v := append(v[0:index], val)
        j.data = append(v, rear...)
    }
    maintRelation(j)
    return j
}

// IsNil 判定data最不是空
func (j *MyJson) IsNil() bool {
    if j.data == nil {
        return true
    }
    return false
}

// Index 传入位置获取slice对应位置的myjson对象
func (j *MyJson) Index(key int) *MyJson {
    m := j.data.([]interface{})
    v := m[key]

    return &MyJson{prev: j,
        previndex: key,
        data:      v}
}

// AppendKey 添加另一个对象到slice的myjson对象中
func (j *MyJson) AppendKey(key interface{}, val interface{}) *MyJson {
    switch v := key.(type) {
    case string:
        m := j.data.(map[string]interface{})
        data := m[v]
        if value, ok := val.(*MyJson); ok {
            m[v] = append(data.([]interface{}), value.Value())
        } else {
            m[v] = append(data.([]interface{}), val)
        }
    case int:
        m := j.data.([]interface{})
        data := m[v]
        if value, ok := val.(*MyJson); ok {
            m[v] = append(data.([]interface{}), value.Value())
        } else {
            m[v] = append(data.([]interface{}), val)
        }
    }
    return j
}

// InsertKey 添加另一个对象到slice的myjson对象中
func (j *MyJson) InsertKey(key string, index int, val interface{}) *MyJson {
    m := j.data.(map[string]interface{})
    v := m[key].([]interface{})
    if value, ok := val.(*MyJson); ok {
        rear := append([]interface{}{}, v[index:]...)
        v := append(v[0:index], value.Value())
        v = append(v, rear...)
        m[key] = v
    } else {
        rear := append([]interface{}{}, v[index:]...)
        v := append(v[0:index], value)
        v = append(v, rear...)
        m[key] = v
    }
    return j
}

// Set 对当前的myjson对象对应key设置值
func (j *MyJson) Set(key interface{}, val interface{}) *MyJson {
    switch v := key.(type) {
    case string:
        m := j.data.(map[string]interface{})
        if value, ok := val.(*MyJson); ok {
            m[v] = value.Value()
        } else {
            m[v] = val
        }
    case int:
        m := j.data.([]interface{})
        if value, ok := val.(*MyJson); ok {
            m[v] = value.Value()
        } else {
            m[v] = val
        }
    }
    return j
}

// Value 返回myjson对象的真实数据
func (j MyJson) Value() interface{} {
    v := j.data
    return v
}

// Len 返回数组对象的长度
func (j MyJson) Len() int {
    v := j.data
    return len(v.([]interface{}))
}

// String方法返回myjson对象的字符串值
func (j MyJson) String() string {
    switch v := j.data.(type) {
    case *MyJson:
        result, err := json.Marshal(v.data)
        if err != nil {
            panic("json to string error" + err.Error())
        }
        return string(result)
    default:
        return ToStr(j.data)
    }
}

// Int 返回myjson对象的真实数据
func (j MyJson) Int() int {
    v := j.data
    return ToInt(v)
}

// Bool 返回myjson对象的真实数据
func (j MyJson) Bool() bool {
    v, ok := j.data.(bool)
    if ok {
        return v
    }
    return false
}

// Array 返回数组对象的真实数据
func (j MyJson) Array() []interface{} {
    v := j.data
    return v.([]interface{})
}

来自 大脸猪 写于 2016-10-24 17:08 -- 更新于2019-04-06 13:32 -- 0 条评论

0条评论

评论: