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"]"
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}
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]
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"
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}}]}
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"`
}
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}
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}