一个请求 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
1
whoami9894 OP 我知道了,貌似是 mgo 报的错
|
2
wangsongyan 2019-05-30 18:44:08 +08:00 via iPhone
如果是因为字段类型不一致,可以试试 json.Number
|
3
petelin 2019-05-30 18:56:20 +08:00 via iPhone
估计有 number 有 string
|
4
whoami9894 OP @wangsongyan
@petelin 感谢回复,我又测试了一下,果然这个 zz 的 API 第一次请求返回 int 之后都返回 string,服了...... ``` 2019/05/30 19:08:29 int 2019/05/30 19:08:29 {"status":0,"msg":"ok","result":{"title":"课本全解( 5 年级上)"," author":null,"subtitle":null,"pubdate":" 2012-7","page":" 236","price":" 21.50 元","s ummary":"","pic":"http:\/\/api.jisuapi.com\/isbn\/\/upload\/3663\/3662449.","isbn":"9787212053928","isbn10":"7212053929","sellerlist":[{"seller":"douban","price":"21.50"}]}} 2019/05/30 19:08:29 89 2019/05/30 19:08:29 json: cannot unmarshal string into Go struct field info.page of type int [GIN] 2019/05/30 - 19:08:29 | 200 | 1.5377224s | 127.0.0.1 | POST /api/v1/isbn-query 2019/05/30 19:10:06 int 2019/05/30 19:10:06 {"status":0,"msg":"ok","result":{"title":"课本全解( 5 年级上)"," subtitle":null,"pic":"http:\/\/api.jisuapi.com\/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"}]}} [GIN] 2019/05/30 - 19:10:06 | 200 | 176.5282ms | 127.0.0.1 | POST /api/v1/isbn-query [GIN] 2019/05/30 - 19:10:16 | 200 | 0s | 127.0.0.1 | POST /api/v1/isbn-query ``` |
5
Trim21 2019-05-30 19:30:25 +08:00 via Android
初学 golang,正好看到这个问题,请教下,这样类型不确定的 json 要怎么解析?
|
6
whoami9894 OP @wangsongyan
@petelin json.Number 有点问题,page 字段可能返回空`"page": null,`,用 json.Number 就报错了`failed to convert json.Number to a number:`,改成了 interface{}暂时测试没什么问题 |
7
whoami9894 OP @Trim21
我这里把 page 定义成空接口类型了,假如之后需要这个确定类型的话再做类型断言就行 |
8
Reficul 2019-05-30 20:23:28 +08:00 8
对于要兼容这种奇葩的字段,可以这样:
type Number int64 然后给这个 Number 实现 json.Unmarshaler 接口来自定义解析逻辑。 |
9
whoami9894 OP @Reficul 感谢回复,学到了
|
11
Allianzcortex 2019-05-30 22:42:35 +08:00 via iPhone
@Reficul 厉害
|
12
JimmyTinsley 2019-05-31 08:59:16 +08:00
我倒是挺好奇这个 api 是怎么实现一会儿返回 int 一会儿返回 string 的...
|
13
wweir 2019-05-31 10:37:44 +08:00
@liujie333333 动态类型语言比较容易出现这样的情况,当然,还是看使用者的水平
|
15
whoami9894 OP @liujie333333
最逗的是这个 API 文档告诉我类型是 string,然后第一次请求返回 string 之后请求全是 int,可能跟服务端某些缓存机制有关 |
16
lxz6597863 2019-06-03 09:10:26 +08:00
https://github.com/json-iterator/go 这个包有个 Any 类型,可以试下
|