"Si un ouvrier veut bien faire son travail, il doit d'abord affûter ses outils." - Confucius, "Les Entretiens de Confucius. Lu Linggong"
Page de garde > La programmation > Comment personnaliser le démarshaling JSON avec Reflection in Go ?

Comment personnaliser le démarshaling JSON avec Reflection in Go ?

Publié le 2024-11-16
Parcourir:365

How to Customize JSON Unmarshaling with Reflection in Go?

Personnalisation de la désorganisation de JSON avec Reflection

Dans Go, la désorganisation de JSON dans une structure est un processus simple. Cependant, lorsqu'il s'agit de champs comportant des balises personnalisées, telles que json:"some_field", le mécanisme de démarshalling standard peut ne pas suffire.

Une approche pour gérer ce scénario consiste à utiliser la réflexion. En inspectant les champs de la structure à l'aide de la réflexion, nous pouvons vérifier si un champ a une balise spécifique et si c'est le cas, gérer sa désorganisation en conséquence.

Dans ce cas particulier, nous voulons nous assurer qu'un champ avec la balise json est non organisé dans un champ de chaîne tel quel. Cela nous permet de gérer des objets ou des tableaux JSON dans notre structure Go.

Exemple de scénario

Considérez les données JSON suivantes et la structure Go :

{
  "I": 3,
  "S": {
    "phone": {
      "sales": "2223334444"
    }
  }
}
type A struct {
    I int64
    S string `sql:"type:json"`
}

Notre objectif est de décomposer le champ « S » en tant que chaîne, en préservant sa structure JSON imbriquée.

Solution utilisant Reflection

Ce qui suit le code montre comment y parvenir en utilisant la réflexion :

func main() {
    a := A{}

    // Unmarshal the JSON data into a byte slice
    var data []byte

    // Iterate over the fields of the struct
    typ := reflect.TypeOf(a)
    val := reflect.ValueOf(a)
    for i := 0; i 

Dans cette approche, nous inspectons manuellement chaque champ de la structure en utilisant la réflexion pour déterminer s'il possède la balise "json". Si tel est le cas, nous désorganisons les données JSON dans le champ sous forme de chaîne.

Solution alternative avec Custom Marshaler et Unmarshaler

Une autre option consiste à implémenter un type personnalisé, comme RawString, qui implémente les interfaces json.Marshaler et json.Unmarshaler. Cela permet plus de flexibilité et de contrôle sur le processus de désorganisation.

Cette approche est démontrée dans le code suivant :

// RawString is a raw encoded JSON object.
// It implements Marshaler and Unmarshaler and can
// be used to delay JSON decoding or precompute a JSON encoding.
type RawString string

// MarshalJSON returns *m as the JSON encoding of m.
func (m *RawString) MarshalJSON() ([]byte, error) {
    return []byte(*m), nil
}

// UnmarshalJSON sets *m to a copy of data.
func (m *RawString) UnmarshalJSON(data []byte) error {
    if m == nil {
        return errors.New("RawString: UnmarshalJSON on nil pointer")
    }
    *m  = RawString(data)
    return nil
}

const data = `{"i":3, "S":{"phone": {"sales": "2223334444"}}}`

type A struct {
    I int64
    S RawString `sql:"type:json"`
}

func main() {
    a := A{}
    err := json.Unmarshal([]byte(data), &a)
    if err != nil {
        log.Fatal("Unmarshal failed", err)
    }
    fmt.Println("Done", a)
}

En implémentant notre propre type, nous pouvons personnaliser le processus de désorganisation et éviter le besoin de réflexion, ce qui aboutit à une solution plus propre et plus efficace.

Dernier tutoriel Plus>

Clause de non-responsabilité: Toutes les ressources fournies proviennent en partie d'Internet. En cas de violation de vos droits d'auteur ou d'autres droits et intérêts, veuillez expliquer les raisons détaillées et fournir une preuve du droit d'auteur ou des droits et intérêts, puis l'envoyer à l'adresse e-mail : [email protected]. Nous nous en occuperons pour vous dans les plus brefs délais.

Copyright© 2022 湘ICP备2022001581号-3