Częściowo JSON unmarshal na mapie w Go
Mój serwer websocket będzie odbierał i odbierał dane JSON. Dane te będą zawsze zawinięte w obiekt z parami klucz / wartość. Klucz-łańcuch będzie działał jako identyfikator wartości, informując serwer Go, jakiego rodzaju jest to wartość. Wiedząc jaki typ wartości, mogę następnie przejść do JSON unmarshal wartość do właściwego typu struktury.
Każdy obiekt json może zawierać wiele par klucz / wartość.
Przykład JSON:
{
"sendMsg":{"user":"ANisus","msg":"Trying to send a message"},
"say":"Hello"
}
Czy Jest jakiś łatwy sposób użycia "encoding/json"
pakietu do zrobić to?
package main
import (
"encoding/json"
"fmt"
)
// the struct for the value of a "sendMsg"-command
type sendMsg struct {
user string
msg string
}
// The type for the value of a "say"-command
type say string
func main(){
data := []byte(`{"sendMsg":{"user":"ANisus","msg":"Trying to send a message"},"say":"Hello"}`)
// This won't work because json.MapObject([]byte) doesn't exist
objmap, err := json.MapObject(data)
// This is what I wish the objmap to contain
//var objmap = map[string][]byte {
// "sendMsg": []byte(`{"user":"ANisus","msg":"Trying to send a message"}`),
// "say": []byte(`"hello"`),
//}
fmt.Printf("%v", objmap)
}
Dzięki za każdą sugestię / pomoc!
2 answers
Można to osiągnąć poprzez Unmarshalling w map[string]*json.RawMessage
.
var objmap map[string]*json.RawMessage
err := json.Unmarshal(data, &objmap)
Aby dalej analizować sendMsg
, możesz zrobić coś w stylu:
var s sendMsg
err = json.Unmarshal(*objmap["sendMsg"], &s)
Dla say
, możesz zrobić to samo i unmarshal w ciągu:
var str string
err = json.Unmarshal(*objmap["say"], &str)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-28 18:37:51
Kontynuując odpowiedź Stephena Weinberga, zaimplementowałem przydatne narzędzie o nazwie iojson , które pomaga w łatwym wypełnianiu danych do istniejącego obiektu, a także kodowaniu istniejącego obiektu do ciągu JSON. Oprogramowanie pośredniczące iojson jest również dostarczane do pracy z innymi urządzeniami pośredniczącymi. Więcej przykładów można znaleźć na stronie https://github.com/junhsieh/iojson
Przykład:
func main() {
jsonStr := `{"Status":true,"ErrArr":[],"ObjArr":[{"Name":"My luxury car","ItemArr":[{"Name":"Bag"},{"Name":"Pen"}]}],"ObjMap":{}}`
car := NewCar()
i := iojson.NewIOJSON()
if err := i.Decode(strings.NewReader(jsonStr)); err != nil {
fmt.Printf("err: %s\n", err.Error())
}
// populating data to a live car object.
if v, err := i.GetObjFromArr(0, car); err != nil {
fmt.Printf("err: %s\n", err.Error())
} else {
fmt.Printf("car (original): %s\n", car.GetName())
fmt.Printf("car (returned): %s\n", v.(*Car).GetName())
for k, item := range car.ItemArr {
fmt.Printf("ItemArr[%d] of car (original): %s\n", k, item.GetName())
}
for k, item := range v.(*Car).ItemArr {
fmt.Printf("ItemArr[%d] of car (returned): %s\n", k, item.GetName())
}
}
}
Przykładowe wyjście:
car (original): My luxury car
car (returned): My luxury car
ItemArr[0] of car (original): Bag
ItemArr[1] of car (original): Pen
ItemArr[0] of car (returned): Bag
ItemArr[1] of car (returned): Pen
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-03 18:36:09