我從佇列收到一個 JSON 物件。我想處理該物件的部分內容並在發送到另一個隊列之前更新它。
如果我有一個輸入
{ "one": "data1", "two": "data2", "three": "data3", ... }
我想採用 one
和 two
並在添加新輸出並發送類似訊息之前計算一些資訊
{ "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中文網其他相關文章!