当前位置: 首页 > 新闻动态 > 网络资讯

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

作者:霞舞 浏览: 发布日期:2026-02-03
[导读]:本文详解Go语言中解析嵌套JSON数组(如{"array":[...]})的完整流程,涵盖结构体字段映射、JSON标签修正、反序列化及遍历操作,并提供可运行示例与关键注意事项。

本文详解 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 数组解析场景。

免责声明:转载请注明出处:http://m.hclxt.cn/news/797838.html

扫一扫高效沟通

多一份参考总有益处

免费领取网站策划SEO优化策划方案

请填写下方表单,我们会尽快与您联系
感谢您的咨询,我们会尽快给您回复!