使用了太长时间的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

Golang的Json encode/decode以及[]byte和string的转换的更多相关文章

  1. Java - byte[] 和 String互相转换

    通过用例学习Java中的byte数组和String互相转换,这种转换可能在很多情况需要,比如IO操作,生成加密hash码等等. 除非觉得必要,否则不要将它们互相转换,他们分别代表了不同的数据,专门服务 ...

  2. C# Byte[] 转String 无损转换

    C# Byte[] 转String 无损转换 转载请注明出处 http://www.cnblogs.com/Huerye/ /// <summary> /// string 转成byte[ ...

  3. [转]关于网络通信,byte[]和String的转换问题

    最近的项目中要使用到把byte[]类型转换成String字符串然后通过网络发送,但发现发现出去的字符串和获取的字符串虽然是一样的,但当用String的getBytes()的方法得到的byte[]跟原来 ...

  4. JSON和Map,List,String互相转换

    1)Map 和 JSON 互相转换 Map 转成 JSON Map<String, List> map = new HashMap<>(); map.put("xAx ...

  5. C#中byte[]与string的转换

    1.        System.Text.UnicodeEncoding converter = new System.Text.UnicodeEncoding();        byte[] i ...

  6. golang []byte和string的高性能转换

    golang []byte和string的高性能转换 在fasthttp的最佳实践中有这么一句话: Avoid conversion between []byte and string, since ...

  7. C#图像处理:Stream 与 byte[] 相互转换,byte[]与string,Stream 与 File 相互转换等

    C# Stream 和 byte[] 之间的转换 一. 二进制转换成图片 MemoryStream ms = new MemoryStream(bytes); ms.Position = 0; Ima ...

  8. golang的json操作

    package main import ( "encoding/json" "fmt" "os" ) type ConfigStruct s ...

  9. node_nibbler:自定义Base32/base64 encode/decode库

    https://github.com/mattrobenolt/node_nibbler 可以将本源码复制到自己需要的JS文件中,比如下面这个文件,一个基于BASE64加密请求参数的REST工具: [ ...

随机推荐

  1. python入门学习:8.类

    python入门学习:8.类 关键点:类 8.1 创建和使用类8.2 使用类和实例8.3 继承8.4 导入类 8.1 创建和使用类   面向对象编程是最有效的软件编写方法之一.在面向对象编程中,你编写 ...

  2. WiFi-ESP8266入门http(2-1)文件系统-复杂结构的网页

    https://blog.csdn.net/solar_Lan/article/details/74231360 用到的网页文件:链接:https://pan.baidu.com/s/1vk6xmsY ...

  3. 简单使用普通用户启动tomcat

    新建用户tomcat,该用户不能登录 useradd tomcat -s '/sbin/nologin' 将/usr/local/tomcat/bin/startup.sh更名 mv /usr/loc ...

  4. redis学习(六)——Sorted Set数据类型

    一.概述: Sorted Set(有序集合)和Set类型极为相似,它们都是字符串的集合,都不允许重复的成员出现在一个Set中.它们之间的主要差别是Sorted Set中的每一个成员都会有一个分数(sc ...

  5. OGC标准服务 WMS WCS WFS WPS

    网络覆盖服务 (WCS) 网络要素服务 (WFS) 网络地图服务 (WMS) 网络地图切片服务 (WMTS) 网络处理服务 (WPS) 1.Web 地图服务(WMS)能够根据用户的请求返回相应的地图( ...

  6. .NET 通过entity framework报数据库连接错误:ORA-01017: invalid username/password; logon denied

    如题,答案为:[ORA-01017].NET程序连接数据库失败 转载文章内容如下: 遇到问题 使用 C#/.NET 开发的一个客户端程序,需要连接 ORACLE 数据库,使用 Oracle.Manag ...

  7. net spider(python 网络爬虫)

    # -*- coding: utf-8 -*- import urllib2,cookielib from bs4 import BeautifulSoup url="http://www. ...

  8. 深入理解Redis Cluster

    Redis Cluster采用虚拟槽分区,所有的key根据哈希函数映射到0~16383槽内,计算公式: slot = CRC16(key) & 16383 每个节点负责维护一部分槽以及槽所映射 ...

  9. Mac 小记 — 杂录

    前言 本篇随笔用于记录一些不好归类和比较简短的 macOs 配置,或者暂存某些记录,方便日后回顾和整理. 按键符号 ⌘ command,⌥ option,⇧ shift,⇪ caps lock,⌃ c ...

  10. prometeus, grafana部署以及监控mysql

    什么是普罗米修斯? Prometheus是一个最初在SoundCloud上构建的开源系统监视和警报工具包 .自2012年成立以来,许多公司和组织都采用了Prometheus,该项目拥有一个非常活跃的开 ...