如何在嵌套结构中解析含已知与未知字段的JSON?
Go解析含已知和未知字段的嵌套JSON
解决方案
要同时解析JSON中已知字段和未知字段,需要为Event结构体自定义JSON反序列化逻辑,具体实现如下:
1. 定义结构体
调整Event结构体,用json:"-"标记X字段,避免默认解析处理,后续通过自定义方法填充:
type Request struct { Common CommonParams `json:"common"` Events []Event `json:"events"` } type CommonParams struct { A string `json:"a"` B string `json:"b"` } type Event struct { C string `json:"c"` X map[string]interface{} `json:"-"` // 忽略默认解析,自行处理 }
2. 实现自定义反序列化方法
为Event实现json.Unmarshaler接口,先解析已知字段,再提取所有未知字段:
func (e *Event) UnmarshalJSON(data []byte) error { // 临时结构体用于提取已知的C字段 type tempEvent struct { C string `json:"c"` } var temp tempEvent // 解析已知字段 if err := json.Unmarshal(data, &temp); err != nil { return err } // 解析所有字段到map var allFields map[string]interface{} if err := json.Unmarshal(data, &allFields); err != nil { return err } // 赋值已知字段,删除map中的已知键,剩余即为未知字段 e.C = temp.C delete(allFields, "c") e.X = allFields return nil }
3. 完整解析示例
以下是完整的解析测试代码:
package main import ( "encoding/json" "fmt" ) type Request struct { Common CommonParams `json:"common"` Events []Event `json:"events"` } type CommonParams struct { A string `json:"a"` B string `json:"b"` } type Event struct { C string `json:"c"` X map[string]interface{} `json:"-"` } func (e *Event) UnmarshalJSON(data []byte) error { type tempEvent struct { C string `json:"c"` } var temp tempEvent if err := json.Unmarshal(data, &temp); err != nil { return err } var allFields map[string]interface{} if err := json.Unmarshal(data, &allFields); err != nil { return err } e.C = temp.C delete(allFields, "c") e.X = allFields return nil } func main() { jsonStr := `{ "common": { "a": "xyz", "b": "qwe" }, "events": [ { "c": "lll", "?": "eee", "??": "ppp" } ] }` var req Request if err := json.Unmarshal([]byte(jsonStr), &req); err != nil { panic(err) } fmt.Printf("Common参数: %+v\n", req.Common) fmt.Printf("Event的C字段值: %s\n", req.Events[0].C) fmt.Printf("未知字段集合: %+v\n", req.Events[0].X) }
原理说明
- 自定义
UnmarshalJSON方法通过两次解析JSON:第一次提取已知的C字段,第二次获取所有字段到map中。 - 删除map中的已知字段键后,剩余的键值对就是JSON中的未知字段,最终赋值给
X字段。 - 这种方式既保留了已知字段的强类型特性,又能灵活接收所有未知字段,完美适配嵌套JSON的解析需求。
内容的提问来源于stack exchange,提问作者khateeb
相关产品推荐
相关产品推荐

