如何正确解析 JSON 数组中的多个 JSON 对象

发布时间 - 2026-02-03 00:00:00    点击率:

本文详解 go 语言中解析嵌套 json 数组(如 `{"array": [...]}`)的完整流程,涵盖结构体字段映射、json 标签修正、反序列化及遍历操作,并提供可运行示例与关键注意事项。

在 Go 中解析形如 {"array": [...]} 的 JSON 响应时,常见错误源于结构体字段名与 JSON 键名不匹配、JSON 标签(json:)书写错误,或顶层结构体未正确对应嵌套层级。以你提供的数据为例,原始 JSON 的顶层键是 "array",而非 "createUserArray";且每个对象中字段如 "entity_title" 应映射为 Go 字段 EntityTitle(而非 EntityTitleName),同时注意拼写一致性(如 "posibble_user_email" 中的 posibble 是故意拼错,需原样保留标签)。

以下是修正后的完整实践方案:

✅ 正确的结构体定义

type MsgCreateUserArray struct {
    CreateUser []MsgCreateUserJson `json:"array"` // 关键:匹配 JSON 中的 "array" 键
}

type MsgCreateUserJson struct {
    EntityTitle       string `json:"entity_title"`        // 原字段名,非 entity_title_name
    EntityOrgName     string `json:"entity_org_name"`
    PossibleUserName  string `json:"possible_user_name"`
    PosibbleUserEmail string `json:"posibble_user_email"` // 注意:JSON 中拼写为 posibble(非 possible)
    UserPositionTitle string `json:"user_position_title"`
    MsgBodyID         int64  `json:"msg_body_id,omitempty"` // 使用 int64 更符合 ID 语义;omitempty 允许缺失
}
⚠️ 注意事项:json:"..." 标签必须严格匹配原始 JSON 的 key 名称(包括大小写和拼写),例如 "posibble_user_email" 不可写作 "possible_user_email";MsgBodyID 推荐使用 int64 而非 string,避免后续数值运算需转换;omitempty 仅在字段值为空(零值)时忽略序列化,对反序列化无影响,但能提升健壮性。

✅ 解析与遍历逻辑

func parseJson(rw http.ResponseWriter, request *http.Request) {
    defer request.Body.Close() // 防止资源泄漏!务必关闭 Body

    decoder := json.NewDecoder(request.Body)
    var payload MsgCreateUserArray

    if err := decoder.Decode(&payload); err != nil {
        http.Error(rw, "Invalid JSON: "+err.Error(), http.StatusBadRequest)
        return
    }

    // 安全遍历数组 —— 即使为空也不会

panic for i, user := range payload.CreateUser { log.Printf("Item %d: %s at %s, position: %s, ID: %d", i+1, user.PossibleUserName, user.EntityTitle, user.UserPositionTitle, user.MsgBodyID, ) // ✅ 此处可对每个 MsgCreateUserJson 对象执行业务逻辑: // 如存入数据库、触发通知、校验邮箱 HTML 内容等 } rw.WriteHeader(http.StatusOK) rw.Write([]byte("Parsed successfully")) }

✅ 完整可运行示例(含测试用 HTTP 请求)

package main

import (
    "encoding/json"
    "log"
    "net/http"
)

// ...(上述结构体定义)

func parseJson(rw http.ResponseWriter, request *http.Request) {
    defer request.Body.Close()
    decoder := json.NewDecoder(request.Body)
    var payload MsgCreateUserArray

    if err := decoder.Decode(&payload); err != nil {
        http.Error(rw, "JSON decode error: "+err.Error(), http.StatusBadRequest)
        return
    }

    log.Printf("Received %d user entries", len(payload.CreateUser))
    for _, u := range payload.CreateUser {
        log.Printf("- %s (%s), %s → ID=%d", 
            u.PossibleUserName, u.UserPositionTitle, u.EntityTitle, u.MsgBodyID)
    }

    rw.WriteHeader(http.StatusOK)
}

func main() {
    http.HandleFunc("/parse", parseJson)
    log.Println("Server starting on :1337...")
    log.Fatal(http.ListenAndServe(":1337", nil))
}

? 测试方式(终端命令)

curl -X POST http://localhost:1337/parse \
  -H "Content-Type: application/json" \
  -d '{
    "array": [
      {
        "entity_title":"University of Phoenix",
        "entity_org_name":"CS Club",
        "possible_user_name":"Johnny Ive",
        "posibble_user_email":"johnny@example.com",
        "user_position_title":"President",
        "msg_body_id":4
      }
    ]
  }'

✅ 总结

  • 结构体字段名无关紧要,json 标签才是反序列化的唯一依据
  • 始终检查 JSON 原始结构(推荐用 jq 或在线 formatter 校验);
  • 使用 defer req.Body.Close() 防止连接泄漏;
  • 遍历时优先用 range 获取值副本(除非需修改原切片);
  • 对于含 HTML 片段的字段(如邮箱链接),后续处理时应做 XSS 过滤或安全解码。

掌握这一模式后,你可轻松扩展支持任意深度嵌套的 JSON 数组解析场景。


# html  # js  # json  # go  # app  # usb  # curl  # ai  # 邮箱  # golang  # xss  # String  # Array  # 结构体  # 切片  # 对象  # http  # 遍历  # 而非  # 序列化  # 字段名  # 这一  # 才是  # 推荐使用  # 你可  # 为例  # 无关紧要 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Laravel如何创建和注册中间件_Laravel中间件编写与应用流程  如何在阿里云虚拟机上搭建网站?步骤解析与避坑指南  Laravel如何使用查询构建器?(Query Builder高级用法)  Laravel如何优雅地处理服务层_在Laravel中使用Service层和Repository层  JS中页面与页面之间超链接跳转中文乱码问题的解决办法  齐河建站公司:营销型网站建设与SEO优化双核驱动策略  Laravel怎么创建控制器Controller_Laravel路由绑定与控制器逻辑编写【指南】  Laravel如何集成微信支付SDK_Laravel使用yansongda-pay实现扫码支付【实战】  javascript基本数据类型及类型检测常用方法小结  Bootstrap整体框架之CSS12栅格系统  Laravel怎么实现软删除SoftDeletes_Laravel模型回收站功能与数据恢复【步骤】  Laravel项目结构怎么组织_大型Laravel应用的最佳目录结构实践  Laravel的路由模型绑定怎么用_Laravel Route Model Binding简化控制器逻辑  Laravel安装步骤详细教程_Laravel环境搭建指南  谷歌浏览器下载文件时中断怎么办 Google Chrome下载管理修复  如何快速搭建高效香港服务器网站?  详解免费开源的.NET多类型文件解压缩组件SharpZipLib(.NET组件介绍之七)  ,交易猫的商品怎么发布到网站上去?  LinuxCD持续部署教程_自动发布与回滚机制  Laravel怎么实现前端Toast弹窗提示_Laravel Session闪存数据Flash传递给前端【方法】  如何在VPS电脑上快速搭建网站?  油猴 教程,油猴搜脚本为什么会网页无法显示?  今日头条微视频如何找选题 今日头条微视频找选题技巧【指南】  在线制作视频的网站有哪些,电脑如何制作视频短片?  Win11搜索不到蓝牙耳机怎么办 Win11蓝牙驱动更新修复【详解】  郑州企业网站制作公司,郑州招聘网站有哪些?  香港服务器网站生成指南:免费资源整合与高速稳定配置方案  如何快速重置建站主机并恢复默认配置?  Laravel怎么判断请求类型_Laravel Request isMethod用法  实例解析angularjs的filter过滤器  Laravel如何升级到最新版本?(升级指南和步骤)  Laravel如何处理和验证JSON类型的数据库字段  Laravel如何自定义错误页面(404, 500)?(代码示例)  详解Android——蓝牙技术 带你实现终端间数据传输  如何在服务器上三步完成建站并提升流量?  PythonWeb开发入门教程_Flask快速构建Web应用  🚀拖拽式CMS建站能否实现高效与个性化并存?  黑客如何通过漏洞一步步攻陷网站服务器?  Laravel如何使用缓存系统提升性能_Laravel缓存驱动和应用优化方案  Laravel如何记录自定义日志?(Log频道配置)  HTML5空格在Angular项目里怎么处理_Angular中空格的渲染问题【详解】  nodejs redis 发布订阅机制封装实现方法及实例代码  如何在Tomcat中配置并部署网站项目?  Laravel如何发送系统通知_Laravel Notifications实现多渠道消息通知  用yum安装MySQLdb模块的步骤方法  如何实现javascript表单验证_正则表达式有哪些实用技巧  Laravel如何实现登录错误次数限制_Laravel自带LoginThrottles限流配置【方法】  JavaScript如何实现类型判断_typeof和instanceof有什么区别  INTERNET浏览器怎样恢复关闭标签页_INTERNET浏览器标签恢复快捷键与方法【指南】  太平洋网站制作公司,网络用语太平洋是什么意思?