当前位置:网站首页>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
边栏推荐
- SQL Server 2016 学习记录 --- 数据更新
- Inside story of Wu xiongang being dismissed by arm: did the establishment of a private investment company harm the interests of shareholders?
- Ueeditor v1.4.3 control file compression
- 华为入股石墨烯材料厂商富烯科技,持股10%
- C language input string with spaces
- Yarn报错:Could not find any valid local directory for nmPrivate/
- IDEA打包jar包及运行jar包命令
- ACM寒假集训#5
- 2020第二届传智杯初赛
- ICML 2022 | 图表示学习的结构感知Transformer模型
猜你喜欢

QT generation Exe file and run without QT environment (enigma virtual box for green executable software packaging) graphic tutorial

IDEA打包jar包及运行jar包命令

AP AUTOSAR platform design 1-2 introduction, technical scope and method

多线程与高并发(三)—— 源码解析 AQS 原理

15. Judge whether the target value exists in the two-dimensional array

机器学习--手写英文字母3--工程特点

ICML 2022 | 图表示学习的结构感知Transformer模型

django-celery-redis异步发邮件

3、MapReduce详解与源码分析

Uni app project directory, file function introduction and development specification
随机推荐
C语言 二级指针详解及示例代码
按位与、或、异或等运算方法
gcc: error trying to exec 'as': execvp: No such file or directory
【栈的应用】--- 中缀表达式转后缀表达式
a different object with the same identifier value was already associated with the session
pt-kill 查询中包含中文字符 导致工具失效的排查
IDEA创建我的第一个项目
2020 second intelligence cup preliminaries
Problem summary file
Aqua Data Studio 18.5.0导出insert语句
Ie compatibility problem handling
试题 历届试题 发现环
4. Adjust the array order so that odd numbers precede even numbers
发力大核、独显!英众科技2020十代酷睿独显产品发布
It is said that the global semiconductor equipment giant may build a joint venture factory in Shanghai!
20200217 training match L1 - 7 2019 is coming (20 points)
ACM winter vacation training 4
机器人技术(RoboCup 2D)实验五十题及主要函数含义
Inverse element & combinatorial number & fast power
a different object with the same identifier value was already associated with the session