go-json operation

https://github.com/antonholmquist/jason

parsing json

must be predefined a struct.

var s Serverslice
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)
type response2 struct {
Page int `json:"page"`
Fruits []string `json:"fruits"`
}

res := response2{}
json.Unmarshal([]byte(str), &res)

json.Decoder vs json.Unmarshal

Go json.Decoder Considered Harmful
short answer is :
Do not use json.Decoder if you are not dealing with JSON streaming.

Use json.Unmarshal:

  • if you don’t know what Go JSON streams are
  • if you are working with a single JSON object at a time
  • if there is a remote possibility that the API may return malformed JSON

arbitrary json operate

package main

import (
"log"
"fmt"
"encoding/json"
"reflect"
)

func main() {
b := []byte(`{"name": "tom", "favNum": 6, "interests": ["knives", "computers"], "usernames": {"github": "TomNomNom", "twitter": "@TomNomNom"}}`)
var f interface{}
err := json.Unmarshal(b, &f)
if err != nil {
log.Fatal("Failed to parse JSON")
}

m := f.(map[string]interface{})

printStruct("", m)

}

func printStruct(prefix string, m map[string]interface{}) {
for k, v := range m {
switch vv := v.(type) {
case string:
fmt.Println(prefix, k, "is string", vv)
case float64:
fmt.Println(prefix, k, "is number", vv)
case []interface{}:
fmt.Println(prefix, k, "is an array:")
for i, u := range vv {
fmt.Println(prefix, i, u)
}
case map[string]interface{}:
fmt.Println(prefix, k, "is a map:")
printStruct(prefix + " ", vv)
default:
fmt.Println(prefix, k, "is a type we can't handle", vv)
}
}
}



//ref: http://michaelheap.com/golang-encodedecode-arbitrary-json/ 18/8/15

// Using some hand crafted JSON. This could come from a file, web service, anything
str2 := `{
"foo": {
"baz": [
1,
2,
3
]
},
"flag": true,
"list": [
"one",
2,
true,
"4",
{
"key": "value"
},
[
1,
true
]
]
}`

var y map[string]interface{}
json.Unmarshal([]byte(str2), &y)

fmt.Printf("%+v\n", y)
//# => map[foo:map[baz:[1 2 3]] flag:true list:[one 2 true 4 map[key:value] [1 true]]]
/*
As we’re un-marshalling into an interface, we need to inform go what data type
each key is before we can perform operations on it. Go provides a the "reflect"
package which we can use to process arbitrarily complex data structures:
*/

the_list := y["list"].([]interface{})
for n, v := range the_list {
fmt.Printf("index:%d value:%v kind:%s type:%s\n", n, v, reflect.TypeOf(v).Kind(), reflect.TypeOf(v))
}

//# =>
//index:0 value:one kind:string type:string
//index:1 value:2 kind:float64 type:float64
//index:2 value:true kind:bool type:bool
//index:3 value:4 kind:string type:string
//index:4 value:map[key:value] kind:map type:map[string]interface {}
//index:5 value:[1 true] kind:slice type:[]interface {}

map to json

// Marshal the map into a JSON string.
empData, err := json.Marshal(emp)
if err != nil {
fmt.Println(err.Error())
return
}

jsonStr := string(empData)