Heim > Backend-Entwicklung > Golang > So entpacken Sie JSON in eine Struktur, ohne alle Elemente zuzuordnen und dabei alle Informationen beizubehalten

So entpacken Sie JSON in eine Struktur, ohne alle Elemente zuzuordnen und dabei alle Informationen beizubehalten

王林
Freigeben: 2024-02-05 21:36:04
nach vorne
481 Leute haben es durchsucht

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

Frageninhalt

Ich erhalte ein JSON-Objekt aus der Warteschlange. Ich möchte einen Teil des Objekts verarbeiten und aktualisieren, bevor ich es an eine andere Warteschlange sende.

Wenn ich einen Input habe

{
  "one": "data1",
  "two": "data2",
  "three": "data3",
  ...
}
Nach dem Login kopieren

Ich möchte einige Informationen nutzen onetwo und berechnen, bevor ich eine neue Ausgabe hinzufüge und eine ähnliche Nachricht sende

{
  "one": "data1UPDATED",
  "two": "data2",
  "three": "data3",
  ...
  "extra_info": "extra"
}
Nach dem Login kopieren

Um die Daten besser verarbeiten zu können, möchte ich das JSON in eine ähnliche Struktur entmarshalieren

type Message struct {
 One string `json:one`
 Two string `json:two`
}
Nach dem Login kopieren

Aber Sie möchten nicht alle Felder zuordnen, da viele davon für diese Anwendung irrelevant sind und andere sich möglicherweise ändern.

Dinge, die ich ausprobiert habe

Ich habe versucht, alle Felder json.RawMessage

zuzuordnen
type Message struct {
 One string `json:"one"`
 Two string `json:"two"`
 ExtraFields json.RawMessage `json:"-"`
}
Nach dem Login kopieren

Beim Marshalling einer Struktur werden die in ExtraFields enthaltenen Felder jedoch nicht berücksichtigt.

{
  "one": "data1",
  "two": "data2"
}
Nach dem Login kopieren

Ich habe auch versucht, ein benutzerdefiniertes Unmarshalling zu schreiben, das die vollständige Nachricht in einer Struktur speichert, mit der nützlichen Nachricht in einem Element und den anderen Informationen in einem anderen Feld

type TmpMessage struct{
  Msg Message
  Others json.RawMessage
}
Nach dem Login kopieren

Aber das wird langsam sehr verwirrend und ich hatte auf eine sauberere Lösung gehofft.

Gibt es eine Möglichkeit, dies zu tun, alternativ ohne Unmarshalling in eine Struktur und nur mit der ursprünglichen map[string] 接口{}的唯一选择?


Richtige Antwort


Sie können einen benutzerdefinierten Unmarshaller schreiben wie:

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
}
Nach dem Login kopieren

Das obige ist der detaillierte Inhalt vonSo entpacken Sie JSON in eine Struktur, ohne alle Elemente zuzuordnen und dabei alle Informationen beizubehalten. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:stackoverflow.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage