如何在 Go 中正确解析 POST 请求返回的 JSON 数组

6次阅读

如何在 Go 中正确解析 POST 请求返回的 JSON 数组

本文详解 go 语言中处理服务器返回 jsON 数组的完整流程,重点解决因结构体json 格式不匹配(如误将数组当作单个对象解码)导致的 json.Unmarshal 错误,并提供可直接运行的代码示例、字段命名规范及健壮性建议。

本文详解 go 语言中处理服务器返回 json 数组的完整流程,重点解决因结构体与 json 格式不匹配(如误将数组当作单个对象解码)导致的 `json.unmarshal` 错误,并提供可直接运行的代码示例、字段命名规范及健壮性建议。

在 Go 中调用 http POST 接口后,若服务端返回的是 JSON 数组(例如 [{“n_expediente”:”9″,”enviar”:”2″}]),而客户端仍按单个对象方式定义结构体并解码(如 var re ResponseFromPost),就会触发 json: cannot unmarshal Array into Go value 类型错误——你看到的 &{%!e(String=array)…} 实际是 fmt.Println 对未成功解码的零值结构体的异常格式化输出,根源在于类型不匹配。

✅ 正确做法:使用切片(slice)接收 JSON 数组

Go 的 json.Unmarshal 要求目标变量类型必须与 JSON 数据结构严格对应。对于数组响应,应声明为结构体切片:

type ResponseItem struct {     NExpediente string `json:"n_expediente"` // 驼峰命名 + json tag 映射下划线字段     Enviar      string `json:"enviar"` }  func main() {     // ... 构造 client 和 req(略)     res, err := client.Do(req)     if err != nil {         log.Fatal("HTTP request failed:", err)     }     defer res.Body.Close()      body, err := io.ReadAll(res.Body) // 替换已弃用的 ioutil.ReadAll     if err != nil {         log.Fatal("Failed to read response body:", err)     }      var responses []ResponseItem // 关键:声明为切片,而非单个结构体     if err := json.Unmarshal(body, &responses); err != nil {         log.Fatal("JSON decode failed:", err)     }      // 安全访问:检查切片长度后再取值     if len(responses) > 0 {         fmt.Println("First item enviar:", responses[0].Enviar)     }      // 遍历所有结果(推荐方式)     for i, item := range responses {         fmt.Printf("Item %d: n_expediente=%s, enviar=%sn", i+1, item.NExpediente, item.Enviar)     } }

⚠️ 关键注意事项

  • JSON Tag 不可省略:Go 结构体字段名默认按首字母大写导出,但 JSON 字段为小写下划线风格(如 “n_expediente”)。必须通过 json:”n_expediente” 显式映射,否则解码失败且无报错(字段保持零值)。
  • 避免命名歧义:原结构体名 ResponseFromPost 易被误解为单个响应,建议改为 ResponseItem 或 PostResponse,并明确其为数组元素类型。
  • 错误处理需分层:HTTP 错误(res.StatusCode != 200)、IO 错误(读取 Body 失败)、JSON 解析错误(Unmarshal 失败)应分别校验,不可仅依赖单一 err。
  • 内存安全:io.ReadAll 会将整个响应体加载到内存,对大响应需考虑流式解析(如 json.Decoder),但本例中小数据量适用。

✅ 总结

当服务端返回 JSON 数组时,Go 客户端必须使用 []YourStruct 切片类型配合 json.Unmarshal,并确保结构体字段通过 json tag 准确映射原始字段名。辅以完善的错误检查与遍历逻辑,即可稳定、清晰地提取所有数据项。

text=ZqhQzanResources