Go语言解析x-www-form-urlencoded嵌套键值对为JSON格式
解析x-www-form-urlencoded嵌套键为JSON结构(Go语言)
Go标准库的url.ParseQuery和HTTP请求的r.Form/r.PostForm只会将notes[key1]这类键当作普通字符串键处理,不会自动解析为嵌套结构。要实现最多3级嵌套的解析,需要手动处理键名的层级拆分,再构建嵌套map,最终序列化为JSON。
实现代码
package main import ( "encoding/json" "fmt" "net/url" "strings" ) // parseNestedFormValues 将url.Values解析为最多3级的嵌套map func parseNestedFormValues(values url.Values) map[string]interface{} { result := make(map[string]interface{}) for key, vals := range values { val := vals[0] // 取键对应的第一个值,如需处理多值可调整逻辑 parts := splitKey(key) switch len(parts) { case 1: result[parts[0]] = val case 2: // 初始化二级map(如果不存在) if _, exists := result[parts[0]]; !exists { result[parts[0]] = make(map[string]interface{}) } result[parts[0]].(map[string]interface{})[parts[1]] = val case 3: // 初始化二级map if _, exists := result[parts[0]]; !exists { result[parts[0]] = make(map[string]interface{}) } level2 := result[parts[0]].(map[string]interface{}) // 初始化三级map if _, exists := level2[parts[1]]; !exists { level2[parts[1]] = make(map[string]interface{}) } level2[parts[1]].(map[string]interface{})[parts[2]] = val } } return result } // splitKey 拆分带[]的嵌套键,返回层级切片,最多拆分3级 func splitKey(key string) []string { var parts []string // 提取第一级键名 firstBracketIdx := strings.Index(key, "[") if firstBracketIdx == -1 { return []string{key} } parts = append(parts, key[:firstBracketIdx]) remaining := key[firstBracketIdx:] // 提取后续层级的键名 for len(parts) < 3 { start := strings.Index(remaining, "[") end := strings.Index(remaining, "]") if start == -1 || end == -1 || start >= end { break } parts = append(parts, remaining[start+1:end]) remaining = remaining[end+1:] } return parts } func main() { // 测试示例请求体 queryStr := "name=abc&age=12¬es[key1]=value1¬es[key2]=value2&user[profile][city]=beijing" values, err := url.ParseQuery(queryStr) if err != nil { fmt.Println("解析请求体失败:", err) return } // 解析为嵌套结构 nestedData := parseNestedFormValues(values) // 序列化为格式化的JSON jsonBytes, err := json.MarshalIndent(nestedData, "", " ") if err != nil { fmt.Println("JSON序列化失败:", err) return } fmt.Println(string(jsonBytes)) }
代码说明
- splitKey函数:负责将
notes[key1]、user[profile][city]这类嵌套键拆分成层级切片,比如["notes", "key1"]、["user", "profile", "city"],超过3级的部分会被忽略。 - parseNestedFormValues函数:遍历所有键值对,根据拆分后的层级长度,构建1-3级的嵌套map结构。如果同一键既有普通值又有嵌套值(如
notes=test¬es[key1]=value1),嵌套值会覆盖普通值,可根据业务需求调整逻辑。 - HTTP请求场景:在处理HTTP请求时,可直接将
r.PostForm或r.Form(需先调用r.ParseForm())传入parseNestedFormValues函数,再将返回的map序列化为JSON即可。
输出示例
运行上述代码后,会输出以下格式化JSON:
{ "age": "12", "name": "abc", "notes": { "key1": "value1", "key2": "value2" }, "user": { "profile": { "city": "beijing" } } }
内容的提问来源于stack exchange,提问作者Monark Dedakiya
相关产品推荐
相关产品推荐

