Mijn websocket-server zal JSON-gegevens ontvangen en demarshallen. Deze gegevens worden altijd verpakt in een object met sleutel/waarde-paren. De key-string fungeert als waarde-ID en vertelt de Go-server wat voor waarde het is. Door te weten welk type waarde, kan ik vervolgens doorgaan met JSON om de waarde in het juiste type struct te brengen.
Elk json-object kan meerdere sleutel/waarde-paren bevatten.
Voorbeeld JSON:
{
"sendMsg":{"user":"ANisus","msg":"Trying to send a message"},
"say":"Hello"
}
Is er een gemakkelijke manier om het pakket "encoding/json"
te gebruiken om dit te doen?
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)
}
Bedankt voor elke vorm van suggestie/hulp!
Antwoord 1, autoriteit 100%
Dit kan worden bereikt door Unmarshaling in een map[string]json.RawMessage
.
var objmap map[string]json.RawMessage
err := json.Unmarshal(data, &objmap)
Om sendMsg
verder te ontleden, kun je zoiets doen als:
var s sendMsg
err = json.Unmarshal(objmap["sendMsg"], &s)
Voor say
kun je hetzelfde doen en een string uit elkaar halen:
var str string
err = json.Unmarshal(objmap["say"], &str)
BEWERKEN:Houd er rekening mee dat je ook de variabelen in je sendMsg-struct moet exporteren om correct te unmarshallen. Dus je structuurdefinitie zou zijn:
type sendMsg struct {
User string
Msg string
}
Voorbeeld: https://play.golang.org/p/OrIjvqIsi4-
Antwoord 2, autoriteit 2%
Hier is een elegante manier om iets soortgelijks te doen. Maar waarom unmarshal gedeeltelijk JSON? Dat slaat nergens op.
- Maak je structuren voor de Chat.
- Decodeer json naar de Struct.
- Je hebt nu gemakkelijk toegang tot alles in Struct/Object.
Kijk hieronder naar de werkende code. Kopieer en plak het.
import (
"bytes"
"encoding/json" // Encoding and Decoding Package
"fmt"
)
var messeging = `{
"say":"Hello",
"sendMsg":{
"user":"ANisus",
"msg":"Trying to send a message"
}
}`
type SendMsg struct {
User string `json:"user"`
Msg string `json:"msg"`
}
type Chat struct {
Say string `json:"say"`
SendMsg *SendMsg `json:"sendMsg"`
}
func main() {
/** Clean way to solve Json Decoding in Go */
/** Excellent solution */
var chat Chat
r := bytes.NewReader([]byte(messeging))
chatErr := json.NewDecoder(r).Decode(&chat)
errHandler(chatErr)
fmt.Println(chat.Say)
fmt.Println(chat.SendMsg.User)
fmt.Println(chat.SendMsg.Msg)
}
func errHandler(err error) {
if err != nil {
fmt.Println(err)
return
}
}
Antwoord 3
Verder naar het antwoord van Stephen Weinberg, heb ik sindsdien een handig hulpmiddel geïmplementeerd iojson , die helpt bij Geef gegevens eenvoudig in op een bestaand object en coderen voor het bestaande object naar een JSON-string. Er is ook een iojson-middleware beschikbaar om met andere middlewares te werken. Meer voorbeelden zijn te vinden op Https://github.com/junhsieh/iojson
Voorbeeld:
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())
}
}
}
Monsteruitgang:
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