如何在Golang中处理JSON请求与响应_解析和序列化数据

Go中处理JSON需用encoding/json包双向转换,关键在定义带json标签的结构体、正确解析请求体、设置响应头并编码,注意时间格式、整数溢出、空值处理及并发安全。

在 Go 中处理 JSON 请求与响应,核心是使用标准库 encoding/json 包完成结构体与 JSON 字节流之间的双向转换。关键在于定义匹配的结构体、正确设置字段标签、处理错误和边界情况。

定义结构体并用 `json` 标签控制序列化行为

Go 的 JSON 编解码依赖结构体字段的可见性(首字母大写)和 json 标签。标签可指定字段名、忽略字段或处理空值:

  • 字段名映射:json:"user_name" 将 Go 字段 UserName 序列化为 user_name
  • 忽略字段:json:"-" 完全跳过该字段
  • 空值处理:json:",omitempty" 在值为零值(""0nil 等)时不输出该字段
  • 嵌套结构支持:结构体字段可直接是另一个结构体,自动递归编码

解析 HTTP 请求中的 JSON 数据

*http.Request 读取并解码 JSON,需注意读取一次、检查 Content-Type、处理解码错误:

  • 先调用 req.Body.Close() 前确保已完整读取,推荐用 io.ReadAll
  • 建议验证 Content-Type 是否为 application/json(非强制但更健壮)
  • 使用 json.Unmarshal 解析字节切片到结构体指针,检查返回错误
  • 若 JSON 字段可能缺失或类型不固定,可用 map[string]interface{}json.RawMessage 延迟解析

构造并返回 JSON 响应

将数据编码为 JSON 并写入 http.ResponseWriter,重点是设置响应头和正确编码:

  • 务必设置 w.Header().Set("Content-Type", "application/json; charset=utf-8")
  • json.NewEncoder(w).Encode(v) 替代 json.Marshal + w.Write,避免中间字节切片,更高效且自动处理错误写入
  • 对错误响应,也应返回合法 JSON(如 {"error": "xxx"}),并配合适当 HTTP 状态码(如 400、500)
  • 敏感字段(如密码)应在结构体中设为私有或用 json:"-" 掩盖,不要依赖前端过滤

处理常见陷阱与增强健壮性

实际开发中容易忽略细节,导致静默失败或安全问题:

  • 时间字段默认序列化为浮点秒数,建议嵌入 time.Time 并实现自定义 MarshalJSON 方法,输出 ISO8601 字符串
  • 整数溢出:JSON 数字无类型,int 字段可能因过大而解码失败,必要时用 int64float64
  • 空数组/对象:Go 中 []string{}nil 都会编码为 [],如需区分,用指针字段或自定义类型
  • 避免全局共享结构体变量;每次请求应创建新实例,防止并发写入冲突