Heim  >  Artikel  >  Backend-Entwicklung  >  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

王林
王林nach vorne
2024-02-05 21:36:04417Durchsuche

如何将 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",
  ...
}

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

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

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:"-"`
}

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

{
  "one": "data1",
  "two": "data2"
}

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
}

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
}

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!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen