golang 使用gorequest 遇到的序列化的坑
golang 序列化的库没其他语言那么好用,然后就掉坑里了。
是用gorequest 库发现的,这个高start 的库,还是有些问题。我使用场景是这样的:
package main import ( "fmt" "github.com/parnurzeal/gorequest" ) type InStruct struct { Param float64 } func main() { postData := InStruct{Param: int64(72057594088097496)} resp, bodyBytes, errs := gorequest.New().Get("http://127.0.0.1:8080").Query(postData).EndBytes() fmt.Println(resp, bodyBytes, errs) }
然后,我发送的数据变成了:Param=72057594088097500。相当于是数据被四舍五入了,一番追查,发现底层做了这个操作,把数据给变了:
func (s *SuperAgent) queryStruct(content interface{}) *SuperAgent { if marshalContent, err := json.Marshal(content); err != nil { s.Errors = append(s.Errors, err) } else { var val map[string]interface{} if err := json.Unmarshal(marshalContent, &val); err != nil {// 这里就会丢精度 s.Errors = append(s.Errors, err) } else { for k, v := range val { k = strings.ToLower(k) var queryVal string switch t := v.(type) { case string: queryVal = t case float64: queryVal = strconv.FormatFloat(t, 'f', -1, 64) case time.Time: queryVal = t.Format(time.RFC3339) default: j, err := json.Marshal(v) if err != nil { continue } queryVal = string(j) } s.QueryData.Add(k, queryVal) } } } return s }
换句话说,就是讲数据由map[string]int64 变成map[string]interface{}, 然后,数据发生了变化。
json 在处理go的数据类型转换时,有个对应关系:
数据类型 | JSON | Golang |
---|---|---|
字串 | string | string |
整数 | number | int64 |
浮点数 | number | flaot64 |
数组 | arrary | slice |
对象 | object | struct |
布尔 | bool | bool |
空值 | null | nil |
在将数字类型unmarshal 转化为interface{} 的时候,默认会先使用浮点数转换,这样,可能会丢失精度。那如何处理?反序列化的时候,将数据类型转换为json.Number 就ok,这样数据会延迟转换,后面可以根据需要转换为int64 或者是 float ,也可以是string。
给个正确的例子,应该使用UseNumber 反序列化:
package main import ( "bytes" "encoding/json" "fmt" ) type Account struct { Email string `json:"email"` Password string `json:"password"` Money int64 `json:"money"` } func main() { account := Account{ Email: "137311107@qq.com", Password: "123", Money: int64(72057594088097496), } deal(account) } func deal(data interface{}) { bdata, err := json.Marshal(data) fmt.Printf("err %v, str %+v\n", err, string(bdata)) var val map[string]interface{} d := json.NewDecoder(bytes.NewBuffer(bdata)) d.UseNumber() err = d.Decode(&val) fmt.Printf("err %v, str %+v\n", err, val) }

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
为监控而生的多级缓存框架 layering-cache
简介 layering-cache是在Spring Cache基础上扩展而来的一个缓存框架,主要目的是在使用注解的时候支持配置过期时间。layering-cache其实是一个两级缓存,一级缓存使用Caffeine作为本地缓存,二级缓存使用redis作为集中式缓存。并且基于redis的Pub/Sub做缓存的删除,所以它是一个适用于分布式环境下的一个缓存系统。 支持 支持缓存监控统计 支持缓存过期时间在注解上直接配置 支持二级缓存的自动刷新(当缓存命中并发现缓存将要过期时会开启一个异步线程刷新缓存) 刷新缓存分为强刷新和软刷新,强刷新直接调用缓存方法,软刷新直接改缓存的时间 缓存Key支持SpEL表达式 新增FastJsonRedisSerializer,KryoRedisSerializer序列化,重写String序列化。 输出INFO级别的监控统计日志 二级缓存是否允许缓存NULL值支持配置 二级缓存空值允许配置时间倍率 集成 集成 Spring 4.x 引入layering-cache maven 方式 <dependency> <groupId>com.gi...
- 下一篇
Oracle推出轻量级Java微服务框架Helidon
近日,Oracle推出了一个新的开源框架Helidon,该项目是一个用于创建基于微服务的应用程序的Java库集合。和Payara Micro、Thorntail(之前的WildFly Swarm)、OpenLiberty、TomEE等项目一样,该项目也加入了MicroProfile家族。 Helidon最初被命名为J4C(Java for Cloud),其设计以简单、快速为目标,它包括两个版本:Helidon SE和Helidon MP。Helidon SE提供了创建微服务的三个核心API:Web服务器、配置和安全,用于构建基于微服务的应用程序,不需要应用服务器。Helidon MP支持用于构建基于微服务的应用程序的MicroProfile 1.1规范。 Web服务器 受NodeJS和其他Java框架的启发,Helidon的Web服务器是一个异步、反应性API,运行在Netty之上。WebServer接口包括对配置、路由、错误处理以及构建度量和健康端点的支持。 下面的示例代码演示了如何启动一个简单的Helidon Web服务器,在一个随机可用的端口上显示“It works!”: //...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2全家桶,快速入门学习开发网站教程
- Windows10,CentOS7,CentOS8安装Nodejs环境
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- 2048小游戏-低调大师作品
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- Linux系统CentOS6、CentOS7手动修改IP地址
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- Docker安装Oracle12C,快速搭建Oracle学习环境