首頁 > 後端開發 > Golang > 主體

如何將 json 解組為結構體而不映射所有元素,同時保留所有訊息

王林
發布: 2024-02-05 21:36:04
轉載
455 人瀏覽過

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

問題內容

我從佇列收到一個 JSON 物件。我想處理該物件的部分內容並在發送到另一個隊列之前更新它。

如果我有一個輸入

{
  "one": "data1",
  "two": "data2",
  "three": "data3",
  ...
}
登入後複製

我想採用 onetwo 並在添加新輸出並發送類似訊息之前計算一些資訊

{
  "one": "data1UPDATED",
  "two": "data2",
  "three": "data3",
  ...
  "extra_info": "extra"
}
登入後複製

為了能夠更好地處理數據,我想將 JSON 解組為類似的結構

type Message struct {
 One string `json:one`
 Two string `json:two`
}
登入後複製

但不想映射所有字段,因為其中許多字段與此應用程式無關,而其他字段可能會更改。

我嘗試過的事情

我嘗試將所有欄位對應到 json.RawMessage

type Message struct {
 One string `json:"one"`
 Two string `json:"two"`
 ExtraFields json.RawMessage `json:"-"`
}
登入後複製

但是,在編組結構時,不包括 ExtraFields 中包含的欄位。

{
  "one": "data1",
  "two": "data2"
}
登入後複製

我還嘗試編寫一種自訂解組,將完整訊息儲存在一個結構中,其中有用訊息儲存在一個元素中,其他資訊儲存在另一個欄位中

type TmpMessage struct{
  Msg Message
  Others json.RawMessage
}
登入後複製

但這變得非常混亂,我希望有一個更簡潔的解決方案。

有沒有辦法做到這一點,或者是不解組到結構並僅使用原始 map[string] 介面{}的唯一選擇?


正確答案


您可以寫一個自訂解組器,例如:

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
}
登入後複製

以上是如何將 json 解組為結構體而不映射所有元素,同時保留所有訊息的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:stackoverflow.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板