Golang Go语言中使用json解析库遇到的问题
Golang Go语言中使用json解析库遇到的问题
一个请求 ISBN 查询 API 的服务,查询信息的字段是:
type info struct {
ISBN string `json:"isbn"`
Title string `json:"title"`
Subtitle string `json:"subtitle"`
Pic string `json:"pic"`
Author string `json:"author"`
Summary string `json:"summary"`
Publisher string `json:"publisher"`
Pubplace string `json:"pubplace"`
Page int `json:"page"`
Price string `json:"price"`
Binding string `json:"binding"`
Keyword string `json:"keyword"`
Edition string `json:"edition"`
Impression string `json:"impression"`
Language string `json:"language"`
Format string `json:"format"`
Class string `json:"class"`
}
这里的 page 最初我写了 string 类型,然后解析报错了json: cannot unmarshal number into Go value of type string
然后我改为了 int 类型,然后依然会时不时报错json: cannot unmarshal string into Go struct field info.page of type int
???昨天报错了几次,之后却一直正常想复现都不行,今天又报错了。查验了那个 ISBN API 应该没有问题,给的 page 就是 integer
但是这里报错后却插入数据库了,逻辑是这样的:
func get(isbn string) (*info, error) {
url := baseURL + isbn
resp, err := nic.Get(url, nil)
if err != nil {
return nil, err
}
t := &tmp{0, "", &info{}}
err = resp.JSON(t) //***************************************** error here
if err != nil {
return nil, err
}
if t.Status != 0 {
return nil, errors.New(t.Msg)
}
return t.Result, nil
}
func query(c *mgo.Collection, isbn string) (*info, error) {
data := &info{}
c.Find(bson.M{“isbn”: isbn}).One(data)
if data.ISBN == "" {
var err error
data, err = get(isbn)
if err != nil {
return nil, err
}
err = c.Insert(data)
if err != nil {
return nil, err
}
}
return data, nil
}
而且第一次报错后插入数据库的数据却是正确的,page 就是正确的 integer:
{'isbn': '9787212053937', 'page': 236, 'price': '21.50', 'binding': '', 'keyword': '', 'edition': '', 'impression': '', 'language': '', 'format': '', 'class': ''}
orz
更多关于Golang Go语言中使用json解析库遇到的问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
我知道了,貌似是 mgo 报的错
更多关于Golang Go语言中使用json解析库遇到的问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
如果是因为字段类型不一致,可以试试 json.Number
估计有 number 有 string
感谢回复,我又测试了一下,果然这个 zz 的 API 第一次请求返回 int 之后都返回 string,服了…<br>2019/05/30 19:08:29 int<br>2019/05/30 19:08:29 {"status":0,"msg":"ok","result":{"title":"课本全解( 5 年级上)","<br>author":null,"subtitle":null,"pubdate":" 2012-7","page":" 236","price":" 21.50 元","s ummary":"","pic":"http:\/\/<a target="_blank" href="http://api.jisuapi.com" rel="nofollow noopener">api.jisuapi.com</a>\/isbn\/\/upload\/3663\/3662449.","isbn":"9787212053928","isbn10":"7212053929","sellerlist":[{"seller":"douban","price":"21.50"}]}}<br>2019/05/30 19:08:29 89<br>2019/05/30 19:08:29 json: cannot unmarshal string into Go struct field info.page of type int<br><br>[GIN] 2019/05/30 - 19:08:29 | 200 | 1.5377224s | 127.0.0.1 | POST /api/v1/isbn-query<br>2019/05/30 19:10:06 int<br>2019/05/30 19:10:06 {"status":0,"msg":"ok","result":{"title":"课本全解( 5 年级上)","<br>subtitle":null,"pic":"http:\/\/<a target="_blank" href="http://api.jisuapi.com" rel="nofollow noopener">api.jisuapi.com</a>\/isbn\/upload\/3663\/3662449.","author":null,"summary":null,"publisher":null,"pubplace":null,"pubdate":" 2012-7","page":236,"price":"21.50","binding":null,"isbn":"9787212053928","isbn10":"7212053929","keyword":null,"edition":null,"impression":null,"language":null,"format":null,"class":null,"sellerlist":[{"seller":"douban","price":"21.50"}]}}<br>[GIN] 2019/05/30 - 19:10:06 | 200 | 176.5282ms | 127.0.0.1 | POST /api/v1/isbn-query<br>[GIN] 2019/05/30 - 19:10:16 | 200 | 0s | 127.0.0.1 | POST /api/v1/isbn-query<br>
初学 golang,正好看到这个问题,请教下,这样类型不确定的 json 要怎么解析?
json.Number 有点问题,page 字段可能返回空"page": null,
,用 json.Number 就报错了failed to convert json.Number to a number:
,改成了 interface{}暂时测试没什么问题
我这里把 page 定义成空接口类型了,假如之后需要这个确定类型的话再做类型断言就行
对于要兼容这种奇葩的字段,可以这样:
type Number int64
然后给这个 Number 实现 json.Unmarshaler 接口来自定义解析逻辑。
感谢回复,学到了
感谢,这个方法好。
我倒是挺好奇这个 api 是怎么实现一会儿返回 int 一会儿返回 string 的…
动态类型语言比较容易出现这样的情况,当然,还是看使用者的水平
最理想是 interface{},什么都能收,然后根据具体类型做处理
最逗的是这个 API 文档告诉我类型是 string,然后第一次请求返回 string 之后请求全是 int,可能跟服务端某些缓存机制有关
https://github.com/json-iterator/go 这个包有个 Any 类型,可以试下
在Go语言中,使用JSON解析库(如标准库中的encoding/json
)时遇到问题,通常可以归结为几类常见错误。以下是一些排查和解决这些问题的建议:
-
数据格式错误:确保JSON数据格式正确,包括正确的引号、逗号、括号等。可以使用在线JSON验证工具检查数据的有效性。
-
类型不匹配:Go结构体中的字段类型必须与JSON数据中的类型一致。例如,JSON中的数字不能映射到Go中的字符串类型。
-
标签使用不当:结构体字段上的
json
标签用于指定JSON字段名。如果标签使用错误(如拼写错误、大小写不匹配),将导致解析失败。 -
嵌套结构:对于复杂的嵌套JSON结构,确保Go中的结构体也正确嵌套,并且每个字段都正确映射。
-
空值处理:JSON中的
null
值在Go中可能无法直接映射到某些类型(如非指针的基本类型)。使用指针或自定义Unmarshal方法处理空值。 -
错误处理:确保在解析JSON时检查并处理
Unmarshal
函数返回的错误。 -
性能问题:对于大型JSON数据,考虑使用流解析(如
encoding/json.Decoder
)以提高性能。
如果以上建议仍未解决问题,建议提供具体的错误信息、JSON数据示例和Go代码片段,以便进一步分析问题所在。同时,查阅官方文档和社区资源也是解决JSON解析问题的好方法。