json序列化是指,将语言中键值对类型的数据转换为json字符串
比如go语言中的结构体、map、数组、切片等,转换为json的格式被称为格式化
在Go中基础库中有一个叫encoding/json
的包是用于处理json字符串的
func Marshal(v interface{}) ([]byte, error)
//Marshal函数接收的是一个空接口类型
//意思是我们可以将go的任意类型的数据传入进去
//而返回值是一个byte的切片,以及error
package main
import (
"encoding/json"
"fmt"
)
type Monster struct{ //我们先定义一个结构体
Name string
Age int
Birthady string
Sal float64
Skill string
}
func main(){
monster := Monster{ //实例化结构体
Name: "牛魔王",
Age: 500,
Birthady: "2011-11-11",
Sal: 8000.0,
Skill: "牛魔拳",
}
data,err := json.Marshal(monster) //通过json包下的Marshal函数对结构体进行转换
if err != nil{
fmt.Printf("序列化错误 err=%v",err)
}
//输出序列化的结果
fmt.Println(string(data))
}
返回
{"Name":"牛魔王","Age":500,"Birthady":"2011-11-11","Sal":8000,"Skill":"牛魔拳"}
package main
import (
"encoding/json"
"fmt"
)
func main(){
//定义一个map
var a map[string]interface{}
a = make(map[string]interface{})
a["name"] = "红孩儿"
a["age"] = 30
a["address"] = "火云洞"
data,err := json.Marshal(a) //将a这个map进行序列化
if err != nil{
fmt.Printf("序列化错误 err=%v",err)
}
fmt.Println(string(data))
}
返回
{"address":"火云洞","age":30,"name":"红孩儿"}
map类型是无序的,所以结果略有不同
package main
import (
"encoding/json"
"fmt"
)
func main(){
var slice []map[string]interface{} //定义一个切片,声明值为空接口
var m1 map[string]interface{}
m1 = make(map[string]interface{})
m1["name"] = "jack"
m1["age"] = "7"
m1["address"] = "北京"
slice = append(slice,m1) //将m1加入切片
var m2 map[string]interface{}
m2 = make(map[string]interface{})
m2["name"] = "tom"
m2["age"] = "20"
m2["address"] = "墨西哥"
slice = append(slice,m2) //将m2加入切片
data,err := json.Marshal(slice) //将切片进行序列化操作
if err != nil{
fmt.Printf("序列化错误 err=%v",err)
}
fmt.Println(string(data))
}
返回:
[{"address":"北京","age":"7","name":"jack"},{"address":"墨西哥","age":"20","name":"tom"}]
### 序列化数组
package main
import (
"encoding/json"
"fmt"
)
var userInfo map[string]interface{}
var userArray [3]interface{}
func main() {
userInfo = make(map[string]interface{})
userInfo["name"] = "august"
userInfo["age"] = 24
userInfo["gender"] = "male"
userArray[0] = userInfo
userArray[1] = userInfo
userArray[2] = userInfo
fmt.Println(userArray)
s_d, _ := json.Marshal(userArray)
fmt.Println(string(s_d))
}
返回:
[{"age":24,"gender":"male","name":"august"},{"age":24,"gender":"male","name":"august"},{"age":24,"gender":"male","name":"august"}]
我们上面序列化结构体的时候,实际上就是把字段的key作为json的key使用
但在浏览器中我们更希望接收到的是首字母小写的字段,为了不破坏结构体调用,可以使用标签
package main
import (
"encoding/json"
"fmt"
)
//定义一个结构体
type Monster struct{
Name string `json:"xxx_name"` //我们在定义结构体的时候,设置好tag json的一个标签
Age int `json:"xxx_age"` //这样在转换时,就会转换为小写
Birthady string
Sal float64
Skill string
}
func main(){
monster := Monster{
Name: "牛魔王" ,
Age: 500,
Birthady: "2011-11-11",
Sal: 8000.0,
Skill: "牛魔拳",
}
data,err := json.Marshal(&monster)
if err != nil{
fmt.Printf("序列化错误 err=%v",err)
}
fmt.Println(string(data))
}
返回:
{"xxx_name":"牛魔王","xxx_age":500,"Birthady":"2011-11-11","Sal":8000,"Skill":"牛魔拳"}
我们在结构体后面添加别名,这样在序列化时导出的就是别名的字段了
我们不能直接将字段定义为小写,这样会影响到其他的包进行调用
就是将我们上面转换的json,重新转换为我们go所使用的数据类型
func Unmarshal(data []byte, v interface{}) error
//传入的值是一个切片类型
//后面的v interface是指定我们用于接收json数据的结构体
//是否接收成功返回一个error的值
package main
import (
"encoding/json"
"fmt"
)
//定义一个结构体,必须要有这个结构体才能去反序列化到结构体
type Monster struct{
Name string
Age int
Birthady string
Sal float64
Skill string
}
func main(){
//我们将这个json写入到变量,不过因为他本身有双引号,这里通过反斜杠将双斜杠转义
//在实际开发中,这个str的字符串是通过前端POST上传或者读取文件得到的
str := "{\"Name\":\"牛魔王\",\"Age\":500,\"Birthady\":\"2011-11-11\",\"Sal\":8000,\"Skill\":\"牛魔拳\"}"
var monster Monster //定义一个结构体,去接收反序列化json的结果
err := json.Unmarshal([]byte(str),&monster) //反序列化,通过[]byte(str)类型断言将str转换为切片
if err != nil{
fmt.Printf("unmarshal err=%v\n",err)
}
fmt.Println(monster)
}
返回:
{牛魔王 500 2011-11-11 8000 牛魔拳}
package main
import (
"encoding/json"
"fmt"
)
func main(){
str := "{\"address\":\"火云洞\",\"age\":30,\"name\":\"红孩儿\"}"
var a map[string]interface{} //定义一个map,必须和要转换的json之前的数据类型相同
//反序列化时,Unmarshal已经封装了make动作,这里就不make了
err := json.Unmarshal([]byte(str),&a) //反序列化,必须传入&a才可使用
if err != nil{
fmt.Printf("unmarshal err=%v\n",err)
}
fmt.Printf("反序列化map后 a=%v",a)
}
返回:
map[address:火云洞 age:30 name:红孩儿]
package main
import (
"encoding/json"
"fmt"
)
func unmarshalSclice(){
str := "[{\"address\":\"北京\",\"age\":\"7\",\"name\":\"jack\"}," +
"{\"address\":\"墨西哥\",\"age\":\"20\",\"name\":\"tom\"}]"
var slice []map[string]interface{} //定义一个切片,同样无需序列化
err := json.Unmarshal([]byte(str),&slice)
if err != nil{
fmt.Printf("unmarshal err=%v\n",err)
}
fmt.Println(slice)
}
返回:
[map[address:北京 age:7 name:jack] map[address:墨西哥 age:20 name:tom]]
在反序列化一个Json字串时,要确保反序列化后的数据类型和原来序列化前的数据类型一致
基于Nginx+Supervisord+uWSGI+Django1.11.1+Python3.6.5构建