Go语言嵌套JSON解析问题:字符串化嵌套JSON无法Unmarshal
兼容两种嵌套JSON格式的Go解析方案
嗨,这个问题我之前也碰到过!默认的json.Unmarshal对类型匹配要求很严格,当你的Data字段在JSON里是字符串化的JSON时,因为和结构体里的map[string]interface{}类型不匹配,就会解析失败导致Data为空。要兼容两种情况,我们可以通过自定义UnmarshalJSON方法来实现灵活解析。
解决方案代码
直接给你上可运行的实现:
package main import ( "encoding/json" "fmt" ) type atomRequest struct { Stream string `json:"stream"` Data map[string]interface{} `json:"data"` } // 自定义JSON反序列化方法,兼容对象和字符串化JSON两种格式 func (a *atomRequest) UnmarshalJSON(data []byte) error { // 定义临时结构体,用json.RawMessage保留Data字段的原始JSON字节 type tempRequest struct { Stream string `json:"stream"` Data json.RawMessage `json:"data"` } var temp tempRequest if err := json.Unmarshal(data, &temp); err != nil { return fmt.Errorf("failed to unmarshal temp struct: %w", err) } // 先赋值Stream字段 a.Stream = temp.Stream // 第一种情况:尝试直接把Data解析成map var dataMap map[string]interface{} if err := json.Unmarshal(temp.Data, &dataMap); err == nil { a.Data = dataMap return nil } // 第二种情况:如果直接解析失败,尝试先解析成字符串,再把字符串内容解析成map var dataStr string if err := json.Unmarshal(temp.Data, &dataStr); err != nil { return fmt.Errorf("data is neither object nor string: %w", err) } if err := json.Unmarshal([]byte(dataStr), &dataMap); err != nil { return fmt.Errorf("failed to unmarshal stringified JSON: %w", err) } a.Data = dataMap return nil } // 测试示例 func main() { // 测试1:正常的嵌套JSON对象 json1 := []byte(`{"stream":"test1","data":{"name":"ohad","age":30}}`) var req1 atomRequest if err := json.Unmarshal(json1, &req1); err != nil { fmt.Printf("Error parsing json1: %v\n", err) } else { fmt.Printf("Parsed json1: %+v\n", req1) } // 测试2:字符串化的嵌套JSON json2 := []byte(`{"stream":"test2","data":"{\"name\":\"ohad\",\"age\":30}"}`) var req2 atomRequest if err := json.Unmarshal(json2, &req2); err != nil { fmt.Printf("Error parsing json2: %v\n", err) } else { fmt.Printf("Parsed json2: %+v\n", req2) } }
代码逻辑说明
- 临时结构体+RawMessage:用
json.RawMessage接收Data字段,这样可以保留原始的JSON字节,而不会被自动解析成错误类型。 - 先尝试直接解析:先把
RawMessage直接解析成map[string]interface{},如果成功,说明是正常的嵌套JSON对象,直接赋值即可。 - Fallback到字符串解析:如果直接解析失败,说明
Data是字符串类型,先把它解析成字符串,再将这个字符串的内容二次解析成map。
边界情况处理
- 如果
Data是null,会直接解析成nil的map,符合预期。 - 如果字符串化的JSON格式无效,会返回明确的错误,方便你排查问题。
内容的提问来源于stack exchange,提问作者OhadBasan
相关产品推荐
相关产品推荐

