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

Cour de récréation

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}

Cour de récréation

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]

Cour de récréation

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"

Cour de récréation

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

Cour de récréation

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} 

Cour de récréation

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} 

Cour de récréation



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow