Recherche…
Syntaxe
- func Marshal (v interface {}) ([] byte, error)
- erreur func Unmarshal (data [] byte, v interface {})
Remarques
Le package "encoding/json"
Package json implémente le codage et le décodage des objets JSON dans Go
.
Les types dans JSON avec leurs types concrets correspondants dans Go sont:
Type JSON | Go Type de béton |
---|---|
booléen | bool |
Nombres | float64 ou int |
chaîne | chaîne |
nul | néant |
Encodage JSON de base
json.Marshal
du package "encoding/json"
encode une valeur sur JSON.
Le paramètre est la valeur à encoder. Les valeurs renvoyées sont un tableau d'octets représentant l'entrée codée JSON (en cas de succès) et une erreur (en cas d'échec).
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"]"
Voici quelques exemples de base de codage pour les types de données intégrés:
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}
Encoder des variables simples est utile pour comprendre comment fonctionne l'encodage JSON dans Go. Cependant, dans la réalité, vous allez probablement encoder des données plus complexes stockées dans des structures .
Décodage JSON de base
json.Unmarshal
du package "encoding/json"
décode une valeur JSON dans la valeur indiquée par la variable donnée.
Les paramètres sont la valeur à décoder en []bytes
et une variable à utiliser comme stockage pour la valeur désérialisée. La valeur renvoyée est une erreur (en cas d'échec).
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]
Remarquez que dans l'exemple ci-dessus, nous connaissions à l'avance le type de la clé et la valeur. Mais ce n'est pas toujours le cas. En fait, dans la plupart des cas, le JSON contient des types de valeurs mixtes.
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"
Dans le dernier exemple ci-dessus, nous avons utilisé une carte générique pour stocker la valeur décodée. Nous devons utiliser une map[string]interface{}
car nous savons que les clés sont des chaînes, mais nous ne connaissons pas le type de leurs valeurs à l'avance.
C'est une approche très simple, mais elle est aussi extrêmement limitée. Dans le monde réel, vous décoderiez généralement un JSON dans un type de struct
personnalisé .
Décodage des données JSON à partir d'un fichier
Les données JSON peuvent également être lues à partir de fichiers.
Supposons que nous ayons un fichier appelé data.json
avec le contenu suivant:
[
{
"Name" : "John Doe",
"Standard" : 4
},
{
"Name" : "Peter Parker",
"Standard" : 11
},
{
"Name" : "Bilbo Baggins",
"Standard" : 150
}
]
L'exemple suivant lit le fichier et décode le contenu:
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)
}
}
Le fichier data.json
doit se trouver dans le même répertoire que le programme exécutable Go. Lisez la documentation d'E / S sur les fichiers Go pour plus d'informations sur l'utilisation des fichiers dans Go.
Utiliser des structures anonymes pour le décodage
Le but de l'utilisation de structures anonymes est de décoder uniquement les informations qui nous intéressent sans que notre application ne soit gaspillée avec des types utilisés uniquement dans une seule fonction.
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)
Sortie: {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}}]}
Pour le cas général, voir aussi: http://stackoverflow.com/documentation/go/994/json/4111/encoding-decoding-go-structs
Configuration des champs de structure JSON
Prenons l'exemple suivant:
type Company struct {
Name string
Location string
}
Masquer / Ignorer certains champs
Pour exporter les Revenue
et les Sales
, mais les masquer du codage / décodage, utilisez json:"-"
ou renommez la variable pour commencer par une lettre minuscule. Notez que cela empêche la variable d'être visible en dehors du package.
type Company struct {
Name string `json:"name"`
Location string `json:"location"`
Revenue int `json:"-"`
sales int
}
Ignorer les champs vides
Pour empêcher que Location
ne soit inclus dans le JSON lorsqu'il est défini sur sa valeur zéro, ajoutez ,omitempty
à la balise json
.
type Company struct {
Name string `json:"name"`
Location string `json:"location,omitempty"`
}
Exemple dans un terrain de jeu
Structures de marshaling avec champs privés
En tant que bon développeur, vous avez créé la structure suivante avec les champs exportés et non exportés:
type MyStruct struct {
uuid string
Name string
}
Exemple dans Playground: https://play.golang.org/p/Zk94Il2ANZ
Maintenant, vous voulez que Marshal()
cette structure en JSON valide pour le stockage dans quelque chose comme etcd. Cependant, depuis que uuid
n'est pas exporté, json.Marshal()
ignore. Que faire? Utilisez une structure anonyme et l'interface json.MarshalJSON()
! Voici un exemple:
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
}
Exemple dans Playground: https://play.golang.org/p/Bv2k9GgbzE
Encodage / décodage à l'aide des structures Go
Supposons que nous ayons la struct
suivante qui définit un type de City
:
type City struct {
Name string
Temperature int
}
Nous pouvons encoder / décoder les valeurs City en utilisant le package encoding/json
.
Tout d'abord, nous devons utiliser les métadonnées Go pour indiquer à l'encodeur la correspondance entre les champs struct et les clés 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
}
Pour garder cet exemple simple, nous déclarons une correspondance explicite entre les champs et les clés. Cependant, vous pouvez utiliser plusieurs variantes des métadonnées json:
comme expliqué dans les documents .
IMPORTANT: seuls les champs exportés (champs avec nom de base) seront sérialisés / désérialisés. Par exemple, si vous nommez le champ t empérature il sera ignoré même si vous définissez l' json
métadonnées.
Codage
Pour encoder une structure City
, utilisez json.Marshal
comme dans l'exemple de base:
// 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}
Décodage
Pour décoder une structure City
, utilisez json.Unmarshal
comme dans l'exemple de base:
// 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}