要将已序列化的 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{})
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
3import (
4 "encoding/json"
5 "fmt"
6 "time"
9func main() {
10 jsonStr := `{ "itanken.cn": { "remain": 99945, "success": 11 }, "com": "result2", "zixizixi.cn": { "remain": 99780, "success": 44 } }`
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
19 fmt.Println("value:\n", value)
20 // 序列化
21 jsonBytes, _ := json.Marshal(value)
22 fmt.Println("JSON:\n", string(jsonBytes))
24 // 结果值
25 result := make(map[string]interface{})
26 result["code"] = 1
27 result["data"] = value // data 必须是一个非序列化值,否则可能会进行二次转义
28 result["time"] = time.Now().UnixNano()
30 // 模拟响应数据到客户端(序列化)
31 resultBytes, _ := json.Marshal(result)
32 fmt.Println("RESULT:\n", string(resultBytes))
33}
复制
标题: Golang 中 JSON 信息值的序列化和反序列化
链接: https://zixizixi.cn/golang-json-serializable
本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可,转载请保留此声明。