Mi websocket servidor recibirá y deserializar los datos JSON. Estos datos siempre va a estar envuelta en un objeto con pares clave/valor. La clave de cadena actuará como identificador de valor, diciendo que el Ir servidor de qué tipo de valor es. Por saber qué tipo de valor, entonces puede proceder a JSON deserializar el valor en el tipo correcto de la estructura.

Cada json-objeto puede contener varios pares clave/valor.

Ejemplo JSON:

{
    "sendMsg":{"user":"ANisus","msg":"Trying to send a message"},
    "say":"Hello"
}

¿Hay alguna forma fácil utilizando el "encoding/json" paquete para hacer esto?

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)
}

Gracias por cualquier tipo de sugerencia/ayuda!

InformationsquelleAutor ANisus | 2012-06-16

2 Comentarios

  1. 170

    Esto puede lograrse mediante el Unmarshalling en un map[string]*json.RawMessage.

    var objmap map[string]*json.RawMessage
    err := json.Unmarshal(data, &objmap)

    A más de analizar sendMsg, entonces puedes hacer algo como:

    var s sendMsg
    err = json.Unmarshal(*objmap["sendMsg"], &s)

    Para say, usted puede hacer la misma cosa y deserializar en una cadena:

    var str string
    err = json.Unmarshal(*objmap["say"], &str)

    EDICIÓN: tenga en cuenta que usted también tendrá que exportar las variables en su sendMsg struct deserializar correctamente. Por lo que su estructura definición sería:

    type sendMsg struct {
        User string
        Msg  string
    }

    Ejemplo: https://play.golang.org/p/RJbPSgBY6gZ

    • Perfecto! Me he perdido ¿cómo podría utilizar RawMessage. Exactamente lo que yo necesitaba. Acerca de say, yo en realidad no se como json.RawMessage, porque la cadena todavía no decodificado (envolver " y escapó \n-personajes, etc), así que voy a deserializar demasiado.
    • Yo fijo mi respuesta para que coincida con lo que usted hizo. Gracias
    • El tipo de mapa[string]*json.RawMessage lugar porque Deserializar/Jefa de métodos que no se implementan en json.RawMessage.
    • me funciona: play.golang.org/p/XYsozrJrSl. Sin embargo, estás en lo correcto de que el uso de un puntero sería mejor. La inversa de mi código no funciona correctamente: play.golang.org/p/46JOdjPpVI. El uso de un puntero corrige esto: play.golang.org/p/ZGwhXkYUT3.
    • Después de actualizar a *json.RawMessage, ahora es necesario eliminar la referencia a ellos en las llamadas a json.Deserializar.
    • Gracias @KyleLemons, actualizado.
    • podemos utilizar map[string] []interface{} para este propósito? usted puede convertir las cosas a los tipos que saben que van a ser para cada tecla.
    • Referencias y resolución de referencias de sendMsg no funciona en mi caso, mientras las referencias y resolución de referencias de decir que funciona bien
    • Sí, debería actualizar mi respuesta. sendMsg necesita tener los campos exportados. Así que tipo de sendMsg struct {Usuario, string Msg}

  2. 1

    Más a Stephen Weinberg la respuesta, desde entonces he implementado una herramienta muy útil llamada iojson, lo que ayuda a llenar los datos a un objeto existente fácilmente así como la codificación del objeto existente a una cadena JSON. Un iojson middleware también se proporciona para trabajar con otros middlewares. Más ejemplos se pueden encontrar en la https://github.com/junhsieh/iojson

    Ejemplo:

    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())
            }
        }
    }

    Ejemplo de salida:

    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

Dejar respuesta

Please enter your comment!
Please enter your name here