Go 编程 | 连载 29 - Go 与 JSON

简介: Go 编程 | 连载 29 - Go 与 JSON

二、Go 与 JSON 的格式映射

在序列化和反序列化时需考虑 JavaScript 和 Go 表示数据类型的方式,Go 是静态强类型语言,JavaScript 是动态弱类型语言。

Go 中声明变量是需要声明数据类型的,即使不声明数据类型 Go 也会在编译器自动判断数据类型,而 JavaScript 则是在运行时才会判断数据类型。 JSON 的数据格式与 JavaScript 相同,JSON 可使用的格式有如下几种:

  • Boolean
  • Number
  • String
  • Array
  • Object
  • Null

但是这些数据类型不会自动映射到 Go 中的数据类型,需要通过 encoding/json 包执行显示的类型转换,JSON 和 Go 中数据类型之间的对应关系如下:

JSON 类型 Go 类型
String string
Boolean bool
Number float64
Array []interface{}
Object map[string]interface{}
Null nil
package main
import (
   "encoding/json"
   "fmt"
   "log"
)
//noinspection ALL
func main() {
   jsonString := `{"name": "stark", "is_vip": "true"}`
   u := User{}
   err := json.Unmarshal([]byte(jsonString), &u)
   if err != nil {
      log.Fatal(err)
   }
   fmt.Println(u)
}
type User struct {
   Name string `json:"name"`
   IsVip bool `json:"is_vip"`
}
复制代码

执行上述代码,输出结果如下:

2022/09/01 11:41:45 json: cannot unmarshal string into Go struct field User.is_vip of type bool
复制代码

上述代码反序列化过程中, Go 会将字符串格式的 true 转换为 bool 类型的 true,因此转换失败导致程序停止。

在进行反序列化时要注意 JavaScript 和 Go 之间的类型对应关系,如果转换时类型不对应则会导致错误。

三、处理 HTTP 收到的 JSON 格式数据

在 Go 语言中通过 HTTP 请求收到的 JSON 数据是以流的形式接收的,既不是字符串也不是字节切片,因此需要通过 encoding/json 标准库中的另一个函数 New.Decoder 来进行解码。

我们通过 Gin 框架快速创建一个返回 JSON 格式的 API,使用 net/http 调用这个 API 获取到 JSON 数据,然后将 JSON 数据转换成结构体实例化对象。

首先新建一个 gin-quickstart 项目,然后通过命令行安装 Gin 框架

go get -u github.com/gin-gonic/gin
复制代码

新建 main.go 文件,添加如下代码:

package main
// 导入 gin 依赖
//noinspection ALL
import (
   "github.com/gin-gonic/gin"
   "net/http"
)
//noinspection ALL
func main(){
   // 创建路由 engine
   r := gin.Default()
   // 创建路由,绑定 handler 函数
   r.GET("/json", ResponseJsonHandler)
   // 启动,绑定端口
   r.Run(":8080")
}
func ResponseJsonHandler (c *gin.Context) {
   d := Data{
      Msg:  "你好 JSON",
      Code: 20000,
   }
   c.JSON(http.StatusOK, d)
}
type Data struct {
   Msg string `json:"msg"`
   Code int `json:"code"`
}
复制代码

运行 main.go 文件,此时我们就已经搭建了一个 HTTP 服务器,在浏览器中访问 http://localhost:8080/json 可以获取如下响应

image.png

接着我们另外一个项目中新建一个 Go 文件,输入如下代码:

package main
//noinspection ALL
import (
   "encoding/json"
   "fmt"
   "log"
   "net/http"
)
//noinspection ALL
func main() {
   data := Data{}
   // 访问 /json API
   res, err := http.Get("http://localhost:8080/json")
   if err != nil {
      log.Fatal(err)
   }
   fmt.Println(res)
   defer res.Body.Close()
   // 处理 JSON 流,将其数据赋值到一个结构体实例化对象 data 上 
   err = json.NewDecoder(res.Body).Decode(&data)
   if err != nil {
      log.Fatal(err)
   }
   fmt.Printf("%+v\n", data)
   fmt.Printf("%T\n", data)
}
type Data struct {
   Msg string `json:"msg"`
   Code int `json:"code"`
}
复制代码

执行上述代码,输出结果如下:

&{200 OK 200 HTTP/1.1 1 1 map[Content-Length:[34] Content-Type:[application/json; charset=utf-8] Date:[Thu, 01 Sep 2022 17:29:25 GMT]] 0xc00015e400 34 [] false false map[] 0xc00017e000 <nil>}
{Msg:你好 JSON Code:20000}
main.Data


相关文章
|
4月前
|
安全 Go 数据处理
Go语言CSP编程实战:通道通信技术
Go语言CSP编程实战:通道通信技术
49 0
|
4月前
|
Go
高效Go语言编程:os包实用技术大揭示
高效Go语言编程:os包实用技术大揭示
46 0
|
2月前
|
SQL 前端开发 Go
编程笔记 GOLANG基础 001 为什么要学习Go语言
编程笔记 GOLANG基础 001 为什么要学习Go语言
|
13天前
|
数据库连接 Go 数据库
【Go 语言专栏】Go 语言中的错误注入与防御编程
【4月更文挑战第30天】本文探讨了Go语言中的错误注入和防御编程。错误注入是故意引入错误以测试系统异常情况下的稳定性和容错性,包括模拟网络故障、数据库错误和手动触发错误。防御编程则强调编写代码时考虑并预防错误,确保程序面对异常时稳定运行。Go语言的错误处理机制包括多返回值和自定义错误类型。结合错误注入和防御编程,可以提升软件质量和可靠性,打造更健壮的系统。开发人员应重视这两方面,以实现更优质的软件产品。
|
13天前
|
网络协议 安全 Go
【Go语言专栏】Go语言中的WebSocket编程
【4月更文挑战第30天】本文介绍了在Go语言中使用WebSocket进行实时Web应用开发的方法。通过第三方包`gorilla/websocket`,开发者可建立WebSocket服务器和客户端。文中展示了如何创建服务器,升级HTTP连接,以及处理读写消息的示例代码。同时,客户端的创建和通信过程也得以阐述。文章还提及WebSocket的生命周期管理、性能与安全性考虑,以及实践中的最佳做法。通过学习,读者将能运用Go语言构建高效、实时的Web应用。
|
13天前
|
算法 Java Go
【Go语言专栏】Go语言中的泛型编程探索
【4月更文挑战第30天】Go语言新引入的泛型编程支持使得代码更通用灵活。通过类型参数在函数和接口定义中实现泛型,如示例中的泛型函数`Swap`和泛型接口`Comparator`。泛型应用包括数据结构、算法实现、函数包装和错误处理,提升代码复用与维护性。这一特性扩展了Go语言在云计算、微服务、区块链等领域的应用潜力。
|
13天前
|
JSON 编解码 Go
【Go语言专栏】Go语言中的JSON编码与解码
【4月更文挑战第30天】Go语言内置JSON编码解码支持,简化了数据交换。`json.Marshal`用于将Go结构体转换为JSON,如示例中`Person`结构体的编码。`json.Unmarshal`则将JSON数据反序列化到结构体,需传入结构体变量的地址。错误处理至关重要,特别是在处理大量数据时,要注意性能优化,如避免不必要的转换和重复操作。了解自定义编码解码和最佳实践能提升开发效率。掌握这些技能,有助于构建高效Go应用。
|
14天前
|
JSON JavaScript 前端开发
Golang深入浅出之-Go语言JSON处理:编码与解码实战
【4月更文挑战第26天】本文探讨了Go语言中处理JSON的常见问题及解决策略。通过`json.Marshal`和`json.Unmarshal`进行编码和解码,同时指出结构体标签、时间处理、omitempty使用及数组/切片区别等易错点。建议正确使用结构体标签,自定义处理`time.Time`,明智选择omitempty,并理解数组与切片差异。文中提供基础示例及时间类型处理的实战代码,帮助读者掌握JSON操作。
23 1
Golang深入浅出之-Go语言JSON处理:编码与解码实战
|
18天前
|
SQL 关系型数据库 MySQL
Golang数据库编程详解 | 深入浅出Go语言原生数据库编程
Golang数据库编程详解 | 深入浅出Go语言原生数据库编程
|
20天前
|
网络协议 Linux Go
Go语言TCP Socket编程(下)
Go语言TCP Socket编程