结构体转json
package main
import (
"encoding/json"
"fmt"
)
// 注意: 结构体转json, 内部成员变量名一定要大写
type IT struct { // 二次编码
Company string `json:"-"` // 定义json不序列化该字段
Subject []string `json:"subj"` // 定义json序列化后的键名为 subj
IsOk bool `json:",string"` // 定义json序列化后的值为string类型, 即"true"
Price float64
}
func main() {
// 初始化结构体
stu := IT{
"人大",
[]string{"Go","Python","C++"},
true,
66.66,
}
// 根据内容生成json格式的 []byte
buf, err := json.Marshal(stu)
//buf, err := json.MarshalIndent(stu, "", " ") // 格式化编码
if err != nil{
fmt.Println(err)
return
}
// buf 是字节切片,需要转换成string
fmt.Println(string((buf)))
}
>>>: {"subj":["Go","Python","C++"],"IsOk":"true","Price":66.66}
map转json
func main() {
m := make(map[string]interface{}, 4)
m["Company"] = "人大"
m["Subject"] = []string{"Go","Python","C++"}
m["IsOk"] = true
m["Price"] = 66.66
r, err := json.Marshal(m)
if err != nil{
return
}
fmt.Println(string(r))
}
>>> :{"Company":"人大","IsOk":true,"Price":66.66,"Subject":["Go","Python","C++"]}
反序列化
json字符串反序列化为结构体
package main
import (
"encoding/json"
"fmt"
)
// 注意: json转结构体时,结构体内部成员变量名与json字符串的键名不一致是,要用 二次编码 来转化
type IT struct { // 二次编码
Company string `json:"company"`
Subject []string `json:"subject"`
IsOk bool `json:"isOk"`
Price float64 `json:"price"`
}
func main() {
// 注意: json字符串内的 键 是小写,而结构体字段名大写
// 所以反序列化到结构体时,要利用结构体的二次编码
jsonBuf := `
{
"company":"人大",
"subject":[
"Go",
"Python",
"C++"
],
"isOk":true,
"price":66.66
}
`
// 定义结构体变量
var it IT
// 反序列: 注意 反序列化时,Unmarshal 是将 []byte 反序列化到目标类型中
err := json.Unmarshal([]byte(jsonBuf), &it) // 注意 这里的结构体要用指针, 原因 值类型,引用类型的问题
if err != nil{
fmt.Println(err)
return
}
fmt.Printf("it: %+v \n", it)
// 反序列只想要的字段
type IT2 struct { // 二次编码
Subject []string `json:"subject"`
}
var it2 IT2
er := json.Unmarshal([]byte(jsonBuf), &it2)
if er != nil{
fmt.Println(err)
return
}
fmt.Printf("it2: %+v \n", it2)
}
>>> it: {Company:人大 Subject:[Go Python C++] IsOk:true Price:66.66}
>>> it2: {Subject:[Go Python C++]}
json字符串反序列化为map
func main() {
// 注意: json字符串内的 键 是小写,而结构体字段名大写
// 所以反序列化到结构体时,要利用结构体的二次编码
jsonBuf := `
{
"company":"人大",
"subject":[
"Go",
"Python",
"C++"
],
"isOk":true,
"price":66.66
}
`
// 反序列化到map
m := make(map[string]interface{}, 4)
e := json.Unmarshal([]byte(jsonBuf), &m) // 注意 这里的map要用指针
if e != nil{
fmt.Println(e)
return
}
fmt.Printf("m: %+v \n", m)
// m: map[company:人大 isOk:true price:66.66 subject:[Go Python C++]]
// 注意: map在接收反序列化的字符串时,map的键值用的是interface{}, 所以下面的方式使用反序列化后map中值,报错
//var str string
//str = m["company"] // 报错
//fmt.Println(string(m["company"])) // 不能转换
// 正确方式 使用类型断言
for _, v := range m{
switch v.(type) {
case string:
fmt.Println(v) // 人大
case float64:
fmt.Println(v) // 66.66
case bool:
fmt.Println(v) // true
case []interface{}: // 注意 反序列化map中的键值为 切片 时,类型为 []interface{} 类型
fmt.Println(v) // Go Python C++]
}
}
利用类型断言取value的值:
var devID string
var paused bool
for _, i := range m{
switch v := i.(type) {
case string:
devID = v
case bool:
paused = v
}
}
也可以这样取值:
switch id := m["company"].(type) {
case string:
devID = id
}
switch p := m["isOk"].(type) {
case bool:
paused = p
}
// 使用接口类型转换,将接口类型转成 string
var svalue interface{}
svalue = "HaiCoder"
if value, ok := svalue.(string); ok{
fmt.Println("Ok Value =", value, "Ok =", ok)
}else{
fmt.Println("Failed Value =", value, "Ok =", ok)
}
}
案例:
前端传输json数据
{
"type":"send",
"path":"/home/ccc/桌面/testFilder/ddd",
"devices":[
"JV2EWHB-P5BWSQD",
"SZKZJ24-VFNXWQ4"
]
}
后端反序列化
func (s *apiService) postAddFolder(w http.ResponseWriter, r *http.Request) {
responseMap := make(map[string]interface{})
defer r.Body.Close()
bs, _ := ioutil.ReadAll(r.Body) //获取post的数据
var data map[string]interface{}
err := json.Unmarshal(bs, &data)
if err != nil {
http.Error(w, err.Error(), 500)
return
}
var folderPath string
switch Path := data["path"].(type) {
case string:
folderPath = Path
}
var folderType string
switch ftype := data["type"].(type) {
case string:
folderType = ftype
}
// 处理数组
var devicesID []interface {}
switch dev := data["devices"].(type) {
case []interface {}:
devicesID = dev
}
for _, devID := range devicesID{
if value, ok := devID.(string); ok{
fmt.Printl(value)
}
}
fmt.Printl(folderPath)
fmt.Printl(folderType)
responseMap["code"] = 2000
responseMap["msg"] = "文件夹添加成功!"
sendJSON(w, responseMap)
}
func sendJSON(w http.ResponseWriter, jsonObject interface{}) {
w.Header().Set("Content-Type", "application/json; charset=utf-8")
bs, err := json.MarshalIndent(jsonObject, "", " ")
if err != nil {
// This Marshal() can't fail though.
bs, _ = json.Marshal(map[string]string{"error": err.Error()})
http.Error(w, string(bs), http.StatusInternalServerError)
return
}
fmt.Fprintf(w, "%s\n", bs)
}