搞定淘宝,京东 api调用返回的奇葩json格式

yangweng · 2015-05-26 06:03:59 · 7778 次点击 · 大约8小时之前 开始浏览    置顶
这是一个创建于 2015-05-26 06:03:59 的主题,其中的信息可能已经有所发展或是发生改变。

淘宝,京东的api调用返回的json格式跟golang的标准库encoding/json中的格式不兼容。 淘宝有些地方习惯性的把float数据加""变成字符串格式 比如 "delivery_score": "0.0", 文档上的又不一样 "delivery_score": 90, 京东的习惯是,不管是不是字符串类型都都加"",变成字符串类型的。 这样就造成标准库无法识别这些格式, 我把json拷贝出来,在decode.go文件的661行的literalStore函数种修改了:字符串处理方式代码如下:

case '"': // string
    s, ok := unquoteBytes(item)
    if !ok {
        if fromQuoted {
            d.error(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
        } else {
            d.error(errPhase)
        }
    }
    num := string(item[1 : len(item)-1])  //value字符串
    switch v.Kind() {
    default:
        d.saveError(&UnmarshalTypeError{"string", v.Type()})
    case reflect.Slice:
        if v.Type() != byteSliceType {
            d.saveError(&UnmarshalTypeError{"string", v.Type()})
            break
        }
        b := make([]byte, base64.StdEncoding.DecodedLen(len(s)))
        n, err := base64.StdEncoding.Decode(b, s)
        if err != nil {
            d.saveError(err)
            break
        }
        v.Set(reflect.ValueOf(b[0:n]))
    case reflect.String:
        v.SetString(string(s))

    case reflect.Interface:
        if v.NumMethod() == 0 {
            v.Set(reflect.ValueOf(num))
        } else {
            d.saveError(&UnmarshalTypeError{"string", v.Type()})
        }
    case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: //整数处理
        n, err := strconv.ParseInt(num, 10, 64)
        if err != nil || v.OverflowInt(n) {
            d.saveError(&UnmarshalTypeError{"number " + num, v.Type()})
            break
        }
        v.SetInt(n)

    case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr://无符号整数处理
        n, err := strconv.ParseUint(num, 10, 64)
        if err != nil || v.OverflowUint(n) {
            d.saveError(&UnmarshalTypeError{"number " + num, v.Type()})
            break
        }
        v.SetUint(n)

    case reflect.Float32, reflect.Float64://浮点数处理
        n, err := strconv.ParseFloat(num, v.Type().Bits())
        if err != nil || v.OverflowFloat(n) {
            d.saveError(&UnmarshalTypeError{"number " + num, v.Type()})
            break
        }
        v.SetFloat(n)
    }

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

7778 次点击  
加入收藏 微博
2 回复  |  直到 2015-05-26 08:06:50
blov
blov · #1 · 10年之前

像PHP这类弱类型语言,json格式就会这样子的,这种不能说是非法吧

yangweng
yangweng · #2 · 10年之前

我没说那个,主要是加强golang的json的兼容性

添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传