子兮子兮 子兮子兮

No can, but will.

目录
Golang 中 JSON 信息值的序列化和反序列化
/        

Golang 中 JSON 信息值的序列化和反序列化

要将已序列化的 JSON 字符串赋值给另一个 JSON 对象中的属性,需要先将 JSON 字符串反序列化。否则返回给客户端的 JSON 结果值可能会是一个包含转义符号 \ 的 JSON 字符串,如下所示:

1{ "code": 1, data: "{ \"itanken.cn\": { \"remain\": 99945, \"success\": 11 }, \"com\": \"result2\", \"zixizixi.cn\": { \"remain\": 99780, \"success\": 44 } }", time: "2021-04-13 20:20:19.123" }

以上 JSON 数据的 data 属性被赋值成了一个存在转义字符字符串。造成这种问题的原因,就是因为在给 data 属性赋值前没有将 JSON 格式的字符串进行反序列化,或者将一个 JSON 格式的数据不小心进行了序列化。

在 Golang 中的 JSON 序列化表示将一个数据对象(如结构体、切片和 map 等)编码为字节数组(通过 string(jsonBytes) 转换为 JSON 格式的字符串,其中 jsonBytes 的数据类型为 []byte),JSON 反序列化表示将一个 JSON 格式的字节数组(通过 []byte(jsonStr) 将 JSON 格式字符串转换为 JSON 的字节数组)解码为对应的结构体、切片或 map 等类型的数据。

反序列化

因为我们想要的 data 属性应该是一个 JSON 对象,所以首先我们要知道的是,在给 data 赋值时,其值必须是一个未序列化的值(未序列化在此处可以理解为非字符串)。在 Golang 中,一个结构体、切片 和 map 等都是未序列化的值,序列化后的值通常为字节数组 []byte 或字符串。要将以上 JSON 数据的 data 赋值为一个 JSON,就要先进行反序列化,任何一个合法的 JSON 格式字符串,都可以反序列化为 map[string]interface{} 类型:

1result := make(map[string]interface{})
2
3jsonStr := "{ \"itanken.cn\": { \"remain\": 99945, \"success\": 11 }, \"com\": \"result2\", \"zixizixi.cn\": { \"remain\": 99780, \"success\": 44 } }"
4value := new(map[string]interface{})
5// 反序列化
6err := json.Unmarshal([]byte(jsonStr), &value)
7if err == nil {
8	result["data"] = value
9}

jsonStr 经过反序列化后再对 data 进行赋值,将 result 进行序列化得到的 JSON 字符串的 data 属性值将不再包含转义符号,因为其值由以前的 JSON 格式字符串变成了一个 JSON 对象。如果给 data 赋值前未将 jsonStr 进行反序列化,或者将 value 进行了序列化,再获取 result 的 JSON 字符串,相当于给 jsonStr 进行了两次序列化,第一次将序列化的 jsonStr 赋值给了 data,此时 data 的值是一个序列化的 JSON 格式字符串,然后将 result 进行序列化的时候 data 的值就发生了第二次序列化,从而包含了转义符号 /

序列化

比如要将 result 返回给客户端,就要经过序列化,将 result 编码为 JSON 格式的字节数组(客户端获取到编码后的字节数组后会进行反序列化得到 JSON 对象)。

1// 模拟响应数据到客户端(序列化)
2resultBytes, _ := json.Marshal(result)
3fmt.Println("RESULT:\n", string(resultBytes))

完整示例代码

 1package main
 2
 3import (
 4	"encoding/json"
 5	"fmt"
 6	"time"
 7)
 8
 9func main() {
10	jsonStr := `{ "itanken.cn": { "remain": 99945, "success": 11 }, "com": "result2", "zixizixi.cn": { "remain": 99780, "success": 44 } }`
11
12	value := new(map[string]interface{})
13	// 反序列化
14	err := json.Unmarshal([]byte(jsonStr), &value)
15	if err != nil {
16		fmt.Println("JSON 字符串反序列化失败:", err.Error())
17		return
18	}
19	fmt.Println("value:\n", value)
20	// 序列化
21	jsonBytes, _ := json.Marshal(value)
22	fmt.Println("JSON:\n", string(jsonBytes))
23
24	// 结果值
25	result := make(map[string]interface{})
26	result["code"] = 1
27	result["data"] = value // data 必须是一个非序列化值,否则可能会进行二次转义
28	result["time"] = time.Now().UnixNano()
29
30	// 模拟响应数据到客户端(序列化)
31	resultBytes, _ := json.Marshal(result)
32	fmt.Println("RESULT:\n", string(resultBytes))
33}