设为首页 收藏本站
查看: 1237|回复: 0

[经验分享] Golang的Json encode/decode以及[]byte和string的转换

[复制链接]

尚未签到

发表于 2018-9-20 09:07:24 | 显示全部楼层 |阅读模式
  使用了太长时间的python,对于强类型的Golang适应起来稍微有点费力,不过操作一次之后发现,只有这么严格的类型规定,才能让数据尽量减少在传输和解析过程中的错误。我尝试使用Golang创建了一个公司的OpenAPI的demo,记录一下中间遇到的问题。
  编码(Encode)Json:
  首先来看下如何将字典编码成Json:
  

// 首先使用字面量来申明和初始化一个字典  
param :
= map[string]int{"page_no": 1, "page_size": 40}  
paramJson, err :
= json.Marshal(param)  

  使用json.Marshal接收需要json.encode的变量。而json.Marshal接收的是interface{}接口变量,该接口变量可以接收任何类型的数据。
  []byte转String以及String转[]byte:
  通常我在python里面使用json.dumps来对字典进行序列化的时候,我通常认为出来的值是一个string,可以将其作为string进行操作。但是这里很明显返回的不是字符串(string)类型,而是一个[]byte类型。所以如果有需要,我们可以将[]byte类型,转换回string进行操作。这里有几种方法可供选择:
  

直接使用:  
string([]byte)
  

  
或使用:
  
String([]byte[:])
  

  ps:现在这两个得到的结果会是一样的,我现在使用的版本是1.8。1.8以前好像会是不同的表现。
  同时我们也会遇到想要将string转换回[]byte的时候。方法如下:
  

[]byte(string)  

  Http包的post请求来实践对Json的序列化反序列化:
  当我们把json编码好之后我们需要将信息传递给服务器。所以用到了http包。
  在使用了之后我觉得go的http包真的非常方便,的确如传言中描述的强大和人性化,方便实用。
  

resp , err := http.PostForm(requestUrl, url.Values{"api_key": {ApiKey}, "api_sign": {apiSign},"param": {string(param)}, "time": {now_time}, "version": {version}})  

  这里我使用http.PostForm方法使用带参数传递的post方法请求服务器。url.Values后面可以跟key[string][]string的形式传递参数。返回一个http.response结构体指针和一个error类型。
  http.response具体带有哪些属性可以详细查看一下包,这里我们会去解析他的Body字段,里面存储着返回的内容:
  

// The Body is automatically dechunked if the server replied  

// with a "chunked" Transfer-Encoding.  
Body io.ReadCloser
  

  这里Body是一个有io.ReadCloser接口的值。io.ReadCloser接口实现了Read()和Write()方法。
  我会用json的Decoder去解析它:
  

var response openApiResponse  
resp :
= request.RequestHeader(paramJson, version, SyncUrl)  
err1 :
= json.NewDecoder(resp.Body).Decode(&response)  

if err1 != nil {  log.Println(err1)
  
}
  return resp
  

  这里json.NewDecoder接收一个有Reader方法的变量,之后我们调用了Decoder的方法decode将里面的内容都存入事先申请好的response结构体变量中。这个变量初始化了我们通过文档了解到的返回的结构体字段类型。
  

openApiResponse struct {  Success    bool   `json:
"success"`  ResultCode int    `json:
"result_code"`  ResultMsg  string `json:
"result_msg"`// 接收JSON字段  Result GoodsSyncResult `json:
"result"`  
}
  

  这样一级一级解析下去,在构造接收返回回来数据的结构体的时候,注意到后面的json字段。他是一个tag,可以在解析json的时候将对应名字的tag解析到对应的变量中。
  这样就相当于你做好了数据结构,然后将对应的数据放到对应的字段里面去。
  当然还有一种办法,当你不知道你所接收数据的数据结构的时候,你是没有办法提前申明好这些数据结构然后来接收的。这时我们可以申明一个空接口interface{},让空接口的指针来接收这组数据,可以查看这组数据的数据结构。
  

var hahaha interface{}  
resp :
= request.RequestHeader(paramJson, version, SyncUrl)  
err1 :
= json.NewDecoder(resp.Body).Decode(&hahaha)  

if err1 != nil {  log.Println(err1)
  
}
  

  上面的hahaha可以接收并decodejson,来接收这组数据。并且可以直接使用fmt.Print之类函数直接打印接收到的数据。如果想直接使用,我们可以使用类型断言但是更推荐的方法是,我们可以根据这组数据来写对应的结构体,然后将数据接收到结构体上进行操作。就像上面一样。
  同样的我们还可以使用一个map[string]interface{}来接收这个Json以方便对其进行后续操作,避免不需要的多余的反射。
  

var hahaha map[string]interface{}  
resp :
= request.RequestHeader(paramJson, version, SyncUrl)  
err1 :
= json.NewDecoder(resp.Body).Decode(&hahaha)  

return hahaha  

  除了实现一个decoder来处理数据,我们往往有Json序列化之后就立即需要序列化的操作,这个同样很容易使用:
  

json.Unmarshal([]byte, &xx)  

  来处理就好了。参数一是需要decode的Json数据, 参数二是用于接收这组数据的结构体字段。同样的我们也可以使用一个空接口来接收数据,也可以使用一一对应的结构体来放置数据。
  看了上面的一堆介绍有一个感觉,就处理Json数据和类型转换来说。。python真是简单到爆炸,一个dumps一个loads轻松搞定。但是Golang严格的参数类型缺可以保证解析过来的数据一定是对应的数据结构和数据类型。不会在类型上报错更为严谨。个人觉得这很有趣,也很喜欢。
  Reference:
  http://stackoverflow.com/questions/3371714/go-string-to-ascii-byte-array  go-string-to-ascii-byte-array
  http://stackoverflow.com/questions/24377907/golang-issue-with-accessing-nested-json-array-after-unmarshalling  golang-issue-with-accessing-nested-json-array-after-unmarshalling
  http://blog.csdn.net/tiaotiaoyly/article/details/38942311  在Go语言中使用JSON



运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-598636-1-1.html 上篇帖子: golang互斥锁和读写锁 下篇帖子: golang中关闭http server
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表