go语言json格式解析与生成示例

packagemain

import(
    "encoding/json"
    "fmt"
    //目前bitly公司开源了一个叫做simplejson的包,在处理未知结构体的JSON时相当方便:https://github.com/bitly/go-simplejson
    "github.com/bitly/go-simplejson"//gogetgithub.com/bitly/go-simplejson
)

typeserverstruct{
    ServerNamestring//如不想到处这个字段,ServerName首字母小写即可
    ServerIPstring
}

typeserverliststruct{
    Servers[]server
}

//例如JSON的key是Foo,那么怎么找对应的字段呢?
//首先查找tag含有Foo的可导出的struct字段(首字母大写)
//其次查找字段名是Foo的导出字段
//最后查找类似FOO或者FoO这样的除了首字母之外其他大小写不敏感的导出字段

/*解析到结构体:我们知晓被解析的JSON数据的结构的前提下采取的方案*/
funcmainstruct(){
    vars serverlist
    str:=`{"servers":[{"serverName":"Shanghai_VPN","serverIP":"127.0.0.1"},{"serverName":"Beijing_VPN","serverIP":"127.0.0.2"}]}`
    json.Unmarshal([]byte(str),&s)
    fmt.Println(s)
}

/*解析到结构体:我们不知道被解析的数据的格式*/
//官方提供的通过interface{}配合断言的方式来解析
/*Go类型和JSON类型的对应关系如下:
bool代表JSONbooleans,
float64代表JSONnumbers,
string代表JSONstrings,
nil代表JSONnull.*/
funcmainassert(){
    b:=[]byte(`{"Name":"Wednesday","Age":6,"Parents":["Gomez","Morticia"]}`)
    varf interface{}
    err:=json.Unmarshal(b,&f)
    iferr !=nil{
        fmt.Printf("error%v",err)
    }
    fmt.Println(f)
    m:=f.(map[string]interface{})
    fork,v :=rangem {
        switchvv :=v.(type){
        casestring:
            fmt.Println(k,"isstring",vv)
        caseint:
            fmt.Println(k,"isint",vv)
        casefloat64:
            fmt.Println(k,"isfloat64",vv)
        case[]interface{}:
            fmt.Println(k,"isanarray:")
            fori,u :=rangevv {
                fmt.Println(i,u)
            }
        default:
            fmt.Println(k,"isofatypeIdon'tknowhowtohandle")
        }
    }
}

//simplejson
funcmainsimplejson(){
    js,_ :=simplejson.NewJson([]byte(`{
"test":{
"array":[1,"2",3],
"int":10,
"float":5.150,
"bignum":9223372036854775807,
"string":"simplejson",
"bool":true
}
}`))

    arr,_ :=js.Get("test").Get("array").Array()
    fmt.Println(arr)
    i,_ :=js.Get("test").Get("int").Int()
    fmt.Println(i)
    ms:=js.Get("test").Get("string").MustString()
    fmt.Println(ms)
    fmt.Println(js.Get("test").Get("bool").MustBool())
}

//生成json

typeServerstruct{
    ServerNamestring`json:"serverName"`//必须通过structtag定义来实现key值的重命名
    ServerIPstring`json:"serverIp"`
}

typeServerslicestruct{
    Servers[]Server`json:"servers"`
}

//Marshal函数只有在转换成功的时候才会返回数据,在转换的过程中我们需要注意几点:
/*JSON对象只支持string作为key,所以要编码一个map,那么必须是map[string]T这种类型(T是Go语言中任意的类型)
Channel,complex和function是不能被编码成JSON的
嵌套的数据是不能编码的,不然会让JSON编码进入死循环
指针在编码的时候会输出指针指向的内容,而空指针会输出null*/

funcmain(){
    vars Serverslice
    s.Servers=append(s.Servers,Server{ServerName:"Shanghai_VPN",ServerIP:"127.0.0.1"})
    s.Servers=append(s.Servers,Server{ServerName:"Beijing_VPN",ServerIP:"127.0.0.2"})
    b,err :=json.Marshal(s)
    iferr !=nil{
        fmt.Println("jsonerr:",err)
    }
    fmt.Println(string(b))
}

//总结
/*针对JSON的输出,我们在定义structtag的时候需要注意的几点是:
字段的tag是"-",那么这个字段不会输出到JSON
tag中带有自定义名称,那么这个自定义名称会出现在JSON的字段名中,例如上面例子中serverName
tag中如果带有"omitempty"选项,那么如果该字段值为空,就不会输出到JSON串中
如果字段类型是bool,string,int,int64等,而tag中带有",string"选项,那么这个字段在输出到JSON的时候会把该字段对应的值转换成JSON字符串*/

//eg:
/*typeServerstruct{
//ID不会导出到JSON中
IDint`json:"-"`

//ServerName2的值会进行二次JSON编码
ServerNamestring`json:"serverName"`
ServerName2string`json:"serverName2,string"`

//如果ServerIP为空,则不输出到JSON串中
ServerIPstring`json:"serverIP,omitempty"`
}

s:=Server{
ID:3,
ServerName:`Go"1.0"`,
ServerName2:`Go"1.0"`,
ServerIP:``,
}
b,_:=json.Marshal(s)
os.Stdout.Write(b)
会输出以下内容:

{"serverName":"Go\"1.0\"","serverName2":"\"Go\\\"1.0\\\"\""}
*/

你可能感兴趣的:(go语言json格式解析与生成示例)