当前位置:网站首页>Go json. Decoder Considered Harmful
Go json. Decoder Considered Harmful
2022-07-28 10:38:00 【Fireflywang】
If you're using Go Language programming , And use json.Decoder Inverse solution JSON load , You may have unexpected effects . You should use json.Unmarshal Instead of json.Decoder.
- json.Decoder It is designed to solve JSON flow , Not complete JSON object .
- json.Decoder Will ignore some illegal JSON grammar .
- json.Decoder The network connection is not released for reuse ( It will slow down HTTP Request to about 4 Multiple duration ).
If you get through json Package documentation , You won't be surprised , Such is the case . I have made mistakes many times . Most developers find using json.Decoder.Decode(...) Than using json.Unmarshal(...) It's easier to parse io.Reader type .
1. json.Decoder by JSON Flow design
JSON Streams are generally in series (concatenated) Or split with a new line JSON value . Here is an example :
{"Name":"Ed"}{"Name":"Sam"}{"Name":"Bob"} Complete streaming content is not a legal JSON, Only the outermost layer is used [ ] It is legal to surround JSON type .
It's just in series JSON object , let me put it another way , It's legal JSON flow .
json.Decoder The type is specially designed for JSON flow . The most likely thing , Yours JSON The load is not suitable for this .
that JSON Why does flow exist ? Can't we use JSON Array ?JSON Stream is mainly used in :
- Store structured data in files , And quickly append without completely parsing the entire file
- from API And other real-time structured streaming data ( Such as
docker logs/docker eventsAPI Wait is to use this method )
If you are parsing a single complete JSON object , Do not use json.Decoder.
2. json.Decoder Will ignore illegal syntax
Not to ignore all illegal grammar , But mixed illegal and legal grammar JSON Flow will be json.Decoder Ignore mistakes . For example, suppose a API return :
{"Name": "Bob"}But the service introduces bug, All of a sudden, it's coming back
{}{"Name": "Bob"}This is obviously illegal JSON load , But it is a legal JSON flow ,json.Decoder Acceptable .
But you don't know this situation , Your code will reverse this return to complete JSON object :
type Person struct {Name string}
...
var v Person
if err := dec.Decode(&v); err != nil {
panic(err)
}
fmt.Println(v.Name) You will get v.Name Is an empty string , There is no mistake .json.Decoder It reverses the first JSON object , The rest is ignored .
Can this happen ? Maybe not , But you can 100% Are you sure? ? Because when it happens, you can't easily debug come out .
3. json.Decoder Not properly exhausted HTTP Connect
This problem was recently solved by Flippo Valsorda Bring up (link), You may be affected by this , Unless you're using Go 1.7 (or above, translator's note ).
If you are creating a HTTP request , Transfer the return body to json.Decoder#Decode() ( Most people will do this ) Then it is very likely that your connection has not been properly exhausted , May make your HTTP The client is slow 4 times .
If HTTP The endpoint returns a single complete JSON object , And you only call json.Decoder#Decode() once , This may mean that you have not read io.EOF Return signal . So you have no basis io.EOF End json.Decoder, The returnee is still open ,TCP Connect ( Or others in use Transport) It cannot be returned to the connection pool even if you have finished reading . For more information, please click URL.
Now in golang The main branch master Has been fixed in , Most likely in Go1.7 In the release .( This article is written in 2016 year 4 month 28 Japan , That fashion has not been released Go1.7)
meanwhile , If your returnee is small enough , Only need to use ioutil.ReadAll Read all into memory and use json.Unmarshal Inverse solution . If you want to keep using json.Decoder, You need to exhaust the unread part of the return body , for example :
io.Copy(ioutil.Discard, resp.Body) therefore , If you are using json.Decoder, Please check your code , Will all defer resp.Body.Close() Replace with :
defer func() {
io.Copy(ioutil.Discard, resp.Body)
resp.Body.Close()
}Conclusion
If you don't handle JSON flow , Please do not use json.Decoder.
Use json.Unmarshal:
- If you don't know Go JSON What is flow
- If you are dealing with a single JSON object
- If remote API It is possible to return the problem JSON
Now you know the trade-off strategy , Then decide for yourself .
Reference material
边栏推荐
- 14. Double pointer - the container that holds the most water
- Aqua Data Studio 18.5.0 export insert statement
- 4. Adjust the array order so that odd numbers precede even numbers
- ACM寒假集训#4
- 中兴通讯:5nm 5G基站芯片正在技术导入!
- 传全球半导体设备巨头或将于上海建合资工厂!
- SQL Server 2016学习记录 --- 连接查询
- 7、MapReduce自定义排序实现
- 9. Delete nodes in the linked list
- SDUT Round #9 2020-新春大作战
猜你喜欢

gcc: error trying to exec 'as': execvp: No such file or directory

SQL Server 2016 学习记录 --- 嵌套查询

markdown转成word或者pdf

SemEval 2022 | 将知识引入NER系统,阿里达摩院获最佳论文奖

逆元&组合数&快速幂
![Database security - create login user + configure permissions [notes]](/img/02/0c3eb542593e8e0a3a62db75c52850.png)
Database security - create login user + configure permissions [notes]

Typora tutorial

Django celery redis send email asynchronously

AP Autosar平台设计 3架构

安装office自定义项 安装期间出错 解决办法
随机推荐
[wechat applet] project practice - lottery application
试题 历届试题 发现环
按位与、或、异或等运算方法
Bitwise and, or, XOR and other operation methods
用两个栈实现一个队列【C语言】
SQL Server 2016 learning records - data update
MySQL的SQL TRACE一例
AP Autosar平台设计 3架构
最短路专题
gcc: error trying to exec 'as': execvp: No such file or directory
胡润发布2020中国芯片设计10强民营企业:华为海思竟然没有上榜!
中芯国际科创板IPO顺利过会,市值有望突破2000亿!
Differences among pipes, pipe passes and pipe States
ICML 2022 | 图表示学习的结构感知Transformer模型
12. Double pointer -- merge two ordered linked lists
Aqua Data Studio 18.5.0导出insert语句
2. Output one of the repeated numbers in the array
9. Delete nodes in the linked list
SDUT Round #9 2020-新春大作战
20200229 training match L1 - 2 delete the substring in the string (20 points)