You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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&notes[key1]=value1&notes[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))
}

代码说明

  1. splitKey函数:负责将notes[key1]、user[profile][city]这类嵌套键拆分成层级切片,比如["notes", "key1"]、["user", "profile", "city"],超过3级的部分会被忽略。
  2. parseNestedFormValues函数:遍历所有键值对,根据拆分后的层级长度,构建1-3级的嵌套map结构。如果同一键既有普通值又有嵌套值(如notes=test&notes[key1]=value1),嵌套值会覆盖普通值,可根据业务需求调整逻辑。
  3. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 10:35:09