Buscar..


Sintaxis

  • Func Marshal (v interfaz {}) ([] byte, error)
  • func Unmarshal (data [] byte, v interface {}) error

Observaciones

El paquete "encoding/json" Package json implementa la codificación y decodificación de objetos JSON en Go .


Los tipos en JSON junto con sus tipos concretos correspondientes en Go son:

Tipo JSON Ir tipo concreto
booleano bool
números float64 o int
cuerda cuerda
nulo nulo

Codificación JSON básica

json.Marshal del paquete "encoding/json" codifica un valor para JSON.

El parámetro es el valor a codificar. Los valores devueltos son una matriz de bytes que representan la entrada codificada JSON (en caso de éxito), y un error (en caso de error).

decodedValue := []string{"foo", "bar"}

// encode the value
data, err := json.Marshal(decodedValue)

// check if the encoding is successful
if err != nil {
    panic(err)
}

// print out the JSON-encoded string
// remember that data is a []byte
fmt.Println(string(data))
// "["foo","bar"]"

Patio de recreo

Aquí hay algunos ejemplos básicos de codificación para tipos de datos incorporados:

var data []byte

data, _ = json.Marshal(1)
fmt.Println(string(data))
// 1

data, _ = json.Marshal("1")
fmt.Println(string(data))
// "1"

data, _ = json.Marshal(true)
fmt.Println(string(data))
// true

data, _ = json.Marshal(map[string]int{"London": 18, "Rome": 30})
fmt.Println(string(data))
// {"London":18,"Rome":30}

Patio de recreo

Codificar variables simples es útil para entender cómo funciona la codificación JSON en Go. Sin embargo, en el mundo real, es probable que codifique datos más complejos almacenados en estructuras .

Decodificación JSON básica

json.Unmarshal del paquete "encoding/json" decodifica un valor JSON en el valor señalado por la variable dada.

Los parámetros son el valor para decodificar en []bytes y una variable para usar como almacenamiento para el valor sin serializar. El valor devuelto es un error (en caso de fallo).

encodedValue := []byte(`{"London":18,"Rome":30}`)

// generic storage for the decoded JSON
var data map[string]interface{}

// decode the value into data
// notice that we must pass the pointer to data using &data
err := json.Unmarshal(encodedValue, &data)

// check if the decoding is successful
if err != nil {
    panic(err)
}

fmt.Println(data)
map[London:18 Rome:30]

Patio de recreo

Observe cómo en el ejemplo anterior sabíamos de antemano tanto el tipo de clave como el valor. Pero este no es siempre el caso. De hecho, en la mayoría de los casos, el JSON contiene tipos de valores mixtos.

encodedValue := []byte(`{"city":"Rome","temperature":30}`)

// generic storage for the decoded JSON
var data map[string]interface{}

// decode the value into data
if err := json.Unmarshal(encodedValue, &data); err != nil {
    panic(err)
}

// if you want to use a specific value type, we need to cast it
temp := data["temperature"].(float64)
fmt.Println(temp) // 30
city := data["city"].(string)
fmt.Println(city) // "Rome"

Patio de recreo

En el último ejemplo anterior, usamos un mapa genérico para almacenar el valor decodificado. Debemos usar una map[string]interface{} porque sabemos que las claves son cadenas, pero no sabemos el tipo de sus valores de antemano.

Este es un enfoque muy simple, pero también es extremadamente limitado. En el mundo real, generalmente decodificaría un JSON en un tipo de struct definido a la medida .

Decodificación de datos JSON de un archivo

Los datos JSON también se pueden leer desde archivos.

Supongamos que tenemos un archivo llamado data.json con el siguiente contenido:

[
    {
      "Name" : "John Doe",
      "Standard" : 4
    },
    {
      "Name" : "Peter Parker",
      "Standard" : 11
    },
    {
      "Name" : "Bilbo Baggins",
      "Standard" : 150
    }
]

El siguiente ejemplo lee el archivo y decodifica el contenido:

package main

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

type Student struct {
    Name     string
    Standard int `json:"Standard"`
}

func main() {
    // open the file pointer
    studentFile, err := os.Open("data.json")
    if err != nil {
        log.Fatal(err)
    }
    defer studentFile.Close()

    // create a new decoder
    var studentDecoder *json.Decoder = json.NewDecoder(studentFile)
    if err != nil {
        log.Fatal(err)
    }

    // initialize the storage for the decoded data
    var studentList []Student
    
    // decode the data
    err = studentDecoder.Decode(&studentList)
    if err != nil {
        log.Fatal(err)
    }

    for i, student := range studentList {
        fmt.Println("Student", i+1)
        fmt.Println("Student name:", student.Name)
        fmt.Println("Student standard:", student.Standard)
    }
}

El archivo data.json debe estar en el mismo directorio del programa ejecutable Go. Lea la documentación de E / S de Go File para obtener más información sobre cómo trabajar con archivos en Go.

Usando estructuras anónimas para decodificar

El objetivo de usar estructuras anónimas es descodificar solo la información que nos importa sin ensuciar nuestra aplicación con tipos que se usan solo en una sola función.

jsonBlob := []byte(`
  {
    "_total": 1,
    "_links": {
      "self": "https://api.twitch.tv/kraken/channels/foo/subscriptions?direction=ASC&limit=25&offset=0",
      "next": "https://api.twitch.tv/kraken/channels/foo/subscriptions?direction=ASC&limit=25&offset=25"
    },
    "subscriptions": [
      {
        "created_at": "2011-11-23T02:53:17Z",
        "_id": "abcdef0000000000000000000000000000000000",
        "_links": {
          "self": "https://api.twitch.tv/kraken/channels/foo/subscriptions/bar"
        },
        "user": {
          "display_name": "bar",
          "_id": 123456,
          "name": "bar",
          "staff": false,
          "created_at": "2011-06-16T18:23:11Z",
          "updated_at": "2014-10-23T02:20:51Z",
          "logo": null,
          "_links": {
            "self": "https://api.twitch.tv/kraken/users/bar"
          }
        }
      }
    ]
  }
`)

var js struct {
    Total int `json:"_total"`
    Links struct {
        Next string `json:"next"`
    } `json:"_links"`
    Subs []struct {
        Created string `json:"created_at"`
        User    struct {
            Name string `json:"name"`
            ID   int    `json:"_id"`
        } `json:"user"`
    } `json:"subscriptions"`
}

err := json.Unmarshal(jsonBlob, &js)
if err != nil {
    fmt.Println("error:", err)
}
fmt.Printf("%+v", js)

Salida: {Total:1 Links:{Next:https://api.twitch.tv/kraken/channels/foo/subscriptions?direction=ASC&limit=25&offset=25} Subs:[{Created:2011-11-23T02:53:17Z User:{Name:bar ID:123456}}]}

Patio de recreo

Para el caso general, consulte también: http://stackoverflow.com/documentation/go/994/json/4111/encoding-decoding-go-structs

Configurando campos de estructura JSON

Considere el siguiente ejemplo:

type Company struct {
    Name     string
    Location string
}

Ocultar / Omitir ciertos campos

Para exportar Revenue y Sales , pero ocultarlos de la codificación / decodificación, use json:"-" o cambie el nombre de la variable para comenzar con una letra minúscula. Tenga en cuenta que esto evita que la variable sea visible fuera del paquete.

type Company struct {
    Name     string `json:"name"`
    Location string `json:"location"`
    Revenue  int    `json:"-"`
    sales    int
}

Ignorar los campos vacíos

Para evitar que la Location se incluya en el JSON cuando se establece en su valor cero, agregue ,omitempty a la etiqueta json .

type Company struct {
    Name     string `json:"name"`
    Location string `json:"location,omitempty"`
}

Ejemplo en Playground

Estructuras de cálculo con campos privados.

Como buen desarrollador, ha creado la siguiente estructura con campos exportados y no exportados:

type MyStruct struct {
    uuid string    
    Name string
}

Ejemplo en Playground: https://play.golang.org/p/Zk94Il2ANZ

Ahora desea convertir a Marshal() esta estructura en JSON válido para almacenamiento en algo así como etcd. Sin embargo, dado que uuid no se exporta, el json.Marshal() omite. ¿Qué hacer? Utilice una estructura anónima y la interfaz json.MarshalJSON() . Aquí hay un ejemplo:

type MyStruct struct {
    uuid string    
    Name string
}

func (m MyStruct) MarshalJSON() ([]byte, error {
    j, err := json.Marshal(struct {
        Uuid string
        Name string
    }{
        Uuid: m.uuid,
        Name: m.Name,
    })
    if err != nil {
           return nil, err
    }
    return j, nil
}

Ejemplo en Playground: https://play.golang.org/p/Bv2k9GgbzE

Codificación / Decodificación utilizando Go structs

Supongamos que tenemos la siguiente struct que define un tipo de City :

type City struct {  
    Name string  
    Temperature int  
}

Podemos codificar / decodificar los valores de la ciudad usando el paquete encoding/json .

En primer lugar, necesitamos usar los metadatos de Go para indicar al codificador la correspondencia entre los campos de estructura y las claves JSON.

type City struct {  
    Name string `json:"name"`  
    Temperature int `json:"temp"`  
    // IMPORTANT: only exported fields will be encoded/decoded  
    // Any field starting with a lower letter will be ignored  
}  

Para mantener este ejemplo simple, declararemos una correspondencia explícita entre los campos y las claves. Sin embargo, puede usar varias variantes de los metadatos de json: como se explica en los documentos .

IMPORTANTE: Solo los campos exportados (campos con nombre de capital) serán serializados / deserializados. Por ejemplo, si el nombre del campo t emperatura será ignorado, incluso si se establece el json metadatos.

Codificación

Para codificar una estructura de City , use json.Marshal como en el ejemplo básico:

// data to encode  
city := City{Name: "Rome", Temperature: 30}  
 
// encode the data  
bytes, err := json.Marshal(city)  
if err != nil {  
    panic(err)  
}  
 
fmt.Println(string(bytes))  
// {"name":"Rome","temp":30} 

Patio de recreo

Descodificación

Para decodificar una estructura de City , use json.Unmarshal como en el ejemplo básico:

// data to decode  
bytes := []byte(`{"name":"Rome","temp":30}`)  
 
// initialize the container for the decoded data  
var city City  
 
// decode the data  
// notice the use of &city to pass the pointer to city  
if err := json.Unmarshal(bytes, &city); err != nil {  
    panic(err)  
}  
 
fmt.Println(city)  
// {Rome 30} 

Patio de recreo



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow