Eswlnk Blog Eswlnk Blog
  • 资源
    • 精彩视频
    • 破解专区
      • WHMCS
      • WordPress主题
      • WordPress插件
    • 其他分享
    • 极惠VPS
    • PDF资源
  • 关于我
    • 论文阅读
    • 关于本站
    • 通知
    • 左邻右舍
    • 玩物志趣
    • 日志
    • 专题
  • 热议话题
    • 游戏资讯
  • 红黑
    • 渗透分析
    • 攻防对抗
    • 代码发布
  • 自主研发
    • 知识库
    • 插件
      • ToolBox
      • HotSpot AI 热点创作
    • 区块
    • 快乐屋
    • 卡密
  • 乱步
    • 文章榜单
    • 热门标签
  • 问答中心反馈
  • 注册
  • 登录
首页 › 日志 › 「开发日志」踩到 Go 的 json 解析坑了,如何才能严格解析 json?

「开发日志」踩到 Go 的 json 解析坑了,如何才能严格解析 json?

Eswlnk的头像
Eswlnk
2023-09-21 13:26:36
「开发日志」踩到 Go 的 json 解析坑了,如何才能严格解析 json?-Eswlnk Blog
智能摘要 AI
作者分享了使用 Go 解析 JSON 时遇到的两个常见问题。第一个问题是,将 JSON 中的 `null` 解析到非指针类型字段时不报错,而是赋值为默认空值,这可能导致业务逻辑错误,如将 `null` 和 `0` 都解析为 `0`。第二个问题是 JSON 中不存在的字段也不会报错,这可能导致未定义字段被解析。作者建议使用 `json.DisallowUnknownFields()` 来避免未知字段的解析,并明确指定字段为指针类型以防止 `null` 被解析为默认值。通过这些措施,可以提高 JSON 解析的安全性和准确性,避免潜在的业务逻辑错误。

引言

最近在使用 Go 进行 json 解析时,遇到了一些问题导致生产环境出错。这篇博客将分享我踩到的两个 json 解析包的坑,并介绍如何进行严格的 json 解析。

「开发日志」踩到 Go 的 json 解析坑了,如何才能严格解析 json?-Eswlnk Blog
GoLang

问题背景

首先,我们假设有以下结构体定义:

type Data struct {
	A   string `json:"a"`
	B   int   `json:"b`
	Obj struct {
		AA string `json:"aa"`
		BB int    `json:"bb"`
	} `json:"obj"`
}

然后,使用 json.Unmarshal() 方法解析以下几种 json 数据:

{"a":null, "b": null, "obj":null}

{"obj": null}

{"a": "a"}

{"a": "a","z":"z"}

{}

{"obj": {}}

问:哪个 json 数据会报错?

答:所有的 json 数据都可以正确解析,不会报错。

解析问题分析

这些问题都是很容易忽略的细节。特别是对于非指针类型的字段,我本能地认为遇到 null 应该会直接报错,但实际上 Go 的 json 解析会将其当作不存在(undefined)来处理。

那么,我们如何才能简单地进行严格的 json 解析呢?我们的要求是:

  1. 不允许出现未知字段,如果出现则报错(可以使用 json 包的 DisallowUnknownFields 实现);
  2. 非指针类型字段不允许传入 null,否则报错(似乎 json 包无法简单实现)。
「开发日志」踩到 Go 的 json 解析坑了,如何才能严格解析 json?-Eswlnk Blog

为什么严格解析很重要?

你可能会好奇为什么将 null 解析为默认空值这个问题那么严重,大家的工作似乎都没有遇到过。通过生产环境中的事故,我认为这绝对是不可接受的。

举个例子,假设有一个名为 price 的 int 类型字段,在 API 接口定义中是非空字段。但是当请求外部 API 或前端发送数据时,却不知道为什么获取到了 {"price" : null} 这样的返回值。由于 json 默认将 null 解析为空值,所以在解析 json 数据时并不会报错,商品价格就会被解析成零元(请注意,0 在业务中是非常常见的,比如商品价格为零是允许的)。这将导致严重的事故,可能导致顾客购买了本不应该购买的商品。

将 null 解析到非指针类型字段并不报错,我认为这是一个非常严重的问题。

解决方案

重新整理一下,可能是我之前表述不够清晰,很多人在使用 Go 的 json 解析时并不关注细节,所以对我的意图没有理解。

例如,我定义了一个名为 Data 的结构体,然后使用以下方法解析 json:err := json.Unmarshal([]byte(jsonStr), &data)

  1. 假设要解析的 json 文本如下,请问:会报错吗?如果不报错,解析的结果是什么?
{"a":null, "b": null, "obj":null}

答案:不会报错,解析后的结果为 {A:"", B:0, Obj:{AA:"", BB:0}}。null 直接被解析为各个类型的默认空值,而不是报错。通常情况下,在 Go 中与 null 最接近的概念是 nil。将 null 解析到非指针类型相当于将 nil 赋值给字段 A、B 和 Obj。如果将报错视为理所当然的事情,那么在实际上 Go 的 json 解析不会报错。

  1. 再假设解析的 json 文本如下:
{}

答案:不会报错,解析后的结果为 {A:"", B:0, Obj:{AA:"", BB:0}}。

  1. 再假设解析的 json 文本如下:
{"a":"jack"}

答案:不会报错,除了字段 a 被赋予了值之外,其他字段都被解析为默认空值,即 {A:"jack", B:0, Obj:{AA:"", BB:0}}。

「开发日志」踩到 Go 的 json 解析坑了,如何才能严格解析 json?-Eswlnk Blog

总结起来,这里存在两个坑:

  1. 将 json 中的 null 解析到非指针类型字段时,并不会报错,而是直接解析为空值。这会导致非常大的问题,因为 {"a": null} 和 {"a": 0} 都会被解析成数字 0。假设你与前端或外部接口约定某些字段不能传入 null 值,但对方却因为 bug 而传入了 null 值,然后成功解析为 0,你该如何处理呢?(在实际业务中,数字 0 是非常常见的正常值,比如价格为 0 或者购买数量为 0)。也许你会说将所有字段定义为指针类型,但是作为后端的我们需要考虑所有字段都可能传入 null 的情况。对于一个复杂的业务 DTO,就会出现指针满天飞的情况,一不留神就会出现 BUG(比如 Calculate() 方法已经有两个 BUG 了,data.Obj1.I 和 data.I 是可空字段,不能直接取值,必须先判空)。
  2. json 中不存在的字段也不会报错。这点可以参考例子中的第 2 和第 3 种情况。目前业务中并没有迫切需要判断这两种情况,但如果将来需要的话,问题会变得非常严重。

结尾

我们应该在进行 json 解析时格外小心,尤其是涉及到 null 值的处理。建议在代码中添加额外的校验和处理逻辑,以确保解析的准确性和安全性。

本站默认网盘访问密码:1166
本站默认网盘访问密码:1166
声明:本站原创文章文字版权归本站所有,转载务必注明作者和出处;本站转载文章仅仅代表原作者观点,不代表本站立场,图文版权归原作者所有。如有侵权,请联系我们删除。
GOjson 解析json 解析包生成环境问题
0
0
Eswlnk的头像
Eswlnk
一个有点倒霉的研究牲站长
赞赏
「壹盾安全」CDN回源网络优化
上一篇
「日志记录」路由器与光猫的选择
下一篇

评论 (0)

请登录以参与评论
现在登录
    发表评论

猜你喜欢

  • 「日志」IG无缘S15总决赛
  • 来自谷歌27岁的生日涂鸦
  • 事件记录:国内网络故障情况
  • 科研记录:ecCodes处理grib文件问题
  • 本站上线邀请码免费兑换系统
Eswlnk的头像

Eswlnk

一个有点倒霉的研究牲站长
1108
文章
319
评论
679
获赞

随便看看

「日志记录」探索安卓国产手机隐藏的DNS秘密
2024-04-04 16:14:31
老站似乎又有百度蜘蛛爬取了
2023-01-20 20:57:17
来自谷歌27岁的生日涂鸦
2025-09-27 22:50:12

文章目录

专题展示

WordPress53

工程实践37

热门标签

360 AI API CDN java linux Nginx PDF PHP python SEO Windows WordPress 云服务器 云服务器知识 代码 免费 安全 安卓 工具 开发日志 微信 微软 手机 插件 攻防 攻防对抗 教程 日志 渗透分析 源码 漏洞 电脑 破解 系统 编程 网站优化 网络 网络安全 脚本 苹果 谷歌 软件 运维 逆向
  • 首页
  • 知识库
  • 地图
Copyright © 2023-2025 Eswlnk Blog. Designed by XiaoWu.
本站CDN由 壹盾安全 提供高防CDN安全防护服务
蜀ICP备20002650号-10
页面生成用时 0.476 秒   |  SQL查询 28 次
本站勉强运行:
友情链接: Eswlnk Blog 网站渗透 倦意博客 特资啦!个人资源分享站 祭夜博客 iBAAO壹宝头条
  • WordPress142
  • 网络安全64
  • 漏洞52
  • 软件52
  • 安全48
现在登录
  • 资源
    • 精彩视频
    • 破解专区
      • WHMCS
      • WordPress主题
      • WordPress插件
    • 其他分享
    • 极惠VPS
    • PDF资源
  • 关于我
    • 论文阅读
    • 关于本站
    • 通知
    • 左邻右舍
    • 玩物志趣
    • 日志
    • 专题
  • 热议话题
    • 游戏资讯
  • 红黑
    • 渗透分析
    • 攻防对抗
    • 代码发布
  • 自主研发
    • 知识库
    • 插件
      • ToolBox
      • HotSpot AI 热点创作
    • 区块
    • 快乐屋
    • 卡密
  • 乱步
    • 文章榜单
    • 热门标签
  • 问答中心反馈