Maison > développement back-end > Golang > le corps du texte

Comment désorganiser JSON dans une structure sans mapper tous les éléments tout en conservant toutes les informations

王林
Libérer: 2024-02-05 21:36:04
avant
454 Les gens l'ont consulté

如何将 json 解组为结构体而不映射所有元素,同时保留所有信息

Contenu de la question

Je reçois un objet JSON de la file d'attente. Je souhaite traiter une partie de l'objet et le mettre à jour avant de l'envoyer vers une autre file d'attente.

Si j'ai une contribution

{
  "one": "data1",
  "two": "data2",
  "three": "data3",
  ...
}
Copier après la connexion

Je veux prendre onetwo et calculer quelques informations avant d'ajouter une nouvelle sortie et d'envoyer un message similaire

{
  "one": "data1UPDATED",
  "two": "data2",
  "three": "data3",
  ...
  "extra_info": "extra"
}
Copier après la connexion

Pour pouvoir mieux traiter les données, je souhaite désorganiser le JSON dans une structure similaire

type Message struct {
 One string `json:one`
 Two string `json:two`
}
Copier après la connexion

Mais je ne veux pas cartographier tous les champs car beaucoup d'entre eux ne sont pas pertinents pour cette application et d'autres peuvent changer.

Choses que j'ai essayées

J'ai essayé de mapper tous les champs sur json.RawMessage

type Message struct {
 One string `json:"one"`
 Two string `json:"two"`
 ExtraFields json.RawMessage `json:"-"`
}
Copier après la connexion

Cependant, lors du regroupement d'une structure, les champs contenus dans ExtraFields ne sont pas inclus.

{
  "one": "data1",
  "two": "data2"
}
Copier après la connexion

J'ai également essayé d'écrire un démarshalling personnalisé qui stocke le message complet dans une structure, avec le message utile dans un élément et les autres informations dans un autre champ

type TmpMessage struct{
  Msg Message
  Others json.RawMessage
}
Copier après la connexion

Mais cela devient très déroutant et j'espérais une solution plus propre.

Existe-t-il un moyen de le faire, alternativement sans procéder au désorganisation dans une structure et en utilisant simplement l'original map[string] 接口{}的唯一选择?


Réponse correcte


Vous pouvez écrire un désorganisateur personnalisé comme :

https://www.php.cn/link/a73d9b34d6f7c322fa3e34c633b1297d

func (m *Message) UnmarshalJSON(data []byte) error {
  tmp := make(map[string]interface{})
  if err := json.Unmarshal(data, &tmp); err != nil {
    return err
  }
  t := reflect.TypeOf(*m)
  for i := 0; i < t.NumField(); i++ {
    f := t.Field(i)
    if f.Name != "ExtraFields" {
      jsonTag := f.Tag.Get("json")
      // this part should probably by a type switch...
      reflect.ValueOf(m).Elem().Field(i).SetString(tmp[jsonTag].(string))
      delete(tmp, jsonTag)
    }
  }
  var err error
  m.ExtraFields, err = json.Marshal(tmp)
  return err
}
Copier après la connexion

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:stackoverflow.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal