本文详解如何使用 go 标准库 `encoding/json` 解析 url 查询参数(如 `filters`)中合法的 json 字符串,并处理常见错误(如非法 json、空值、类型不匹配),附完整可运行示例。
在 Go Web 开发中,常需从 HTTP 请求的查询字符串中提取结构化数据(如过滤条件)。但需特别注意:URL 查询参数本身不是自动解析的 JSON——它只是普通字符串,且必须符合 JSON 语法规范才能被 json.Unmarshal 正确解析。
例如,原始问题中的 URL:
http://127.0.0.1:3001/find?field=hostname&field=App&filters=["hostname":"example.com,"type":"vm"]
该 filters 值存在两个严重问题:
✅ 正确的 URL 应将 filters 设为标准 JSON 对象字符串:
...&filters={"hostname":"example.com","type":"vm"}以下是在 http.HandlerFunc 中安全解析 filters 参数的推荐写法:
func handleFind(w http.ResponseWriter, r *http.Request) {
// 1. 获取 filters 查询参数值(注意:Get() 返回单个字符串,避免索引越界)
filtersStr := r.URL.Query().Get("filters")
if filtersStr == "" {
http.Error(w, "missing 'filters' parameter", http.StatusBadRequest)
return
}
// 2. 定义目标结构体(比 map[string]string 更类型安全、可扩展)
var filters struct {
Hostname string `json:"hostname"`
Type string `json:"type"`
// 可按需添加其他字段,如 Status, Region 等
}
// 3. 解析 JSON 字符串
if err := json.Unmarshal([]byte(filtersStr), &filters); err != nil {
http.Error(w, "invalid JSON in 'filters': "+err.Error(), http.StatusBadRequest)
return
}
// 4. 使用解析结果
fmt.Printf("Hostname: %s, Type: %s\n", filters.Hostname, filters.Type)
// 输出:Hostname: example.com, Type: vm
}
nic(切片越界);解析 URL 中的 JSON 参数 = 正确构造(服务端/客户端) + 安全获取(Query().Get) + 类型化解码(json.Unmarshal) + 全面错误处理。跳过任一环节都可能导致 panic、静默失败或安全漏洞。坚持使用结构体定义 schema,是写出可维护 Go Web API 的关键实践。