http协议前后端的交互通过json字符串交互,在Go语言中,序列化与反序列化 需要结构体 的转化。

1、序列化为 Json 字符串

1.1 json.Marshl 序列化

func Marshal(v interface{}) ([]byte, error) 
// 定义 Student类结构体
type Student struct {
	Code    int         `json:"code"`    // 使用tag,表示对应json的字段名
	Message string      `json:"message"`
	Grades  []GradeType `json:"grades"`  // 结构体类数组
}
type GradeType struct {
	GradeClass string `json:"gradeClass"`
	Score      ScoreType
}
type ScoreType struct {
	Chinese int `json:"chinese"`
	English int `json:"english"`
}

初始化结构体,通过json.Marshal转为json字符串

func main() {
	stu := Student{
		Code:    0,
		Message: "success",
		Grades: []GradeType{
			GradeType{
				GradeClass: "一年级",
				Score: ScoreType{
					Chinese: 99,
					English: 88,
				},
			},
			GradeType{
				GradeClass: "二年级",
				Score: ScoreType{
					Chinese: 100,
					English: 98,
				},
			},
		},
	}

	fmt.Println(stu)

	s, err := json.Marshal(stu)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(s)         // [123 34 99 111 100 101 34 58 48...23 135]
	fmt.Printf("%T\n", s)  // []uint8,这里为char字节数组类型
	fmt.Println(string(s)) // 字节类型转 字符串,通过 string 直接转换
	// {"code":0,"message":"success","grades":[{"gradeClass":"一年级","Score":{"chinese":99,"english":88}},{"gradeClass":"二年级","Score":{"chinese":100,"english":98}}]}
}

1.2 Golang 优雅的输出 json字符串

为增强json字符串可读性,可调用开源的

  • 安装
go get -u github.com/tidwall/pretty
{"name":  {"first":"Tom","last":"Anderson"},  "age":37,
"children": ["Sara","Alex","Jack"],
"fav.movie": "Deer Hunter", "friends": [
    {"first": "Janet", "last": "Murphy", "age": 44}
  ]}
result = pretty.Pretty(example)
{
  "name": {
    "first": "Tom",
    "last": "Anderson"
  },
  "age": 37,
  "children": ["Sara", "Alex", "Jack"],
  "fav.movie": "Deer Hunter",
  "friends": [
    {
      "first": "Janet",
      "last": "Murphy",
      "age": 44
    }
  ]
}

2、反序列化为 struct 结构体

2.1 json.Unmarshl 反序列化

需求:将json字符串转为结构体,1)预先定义json对应的结构体类型;2)调用 json.Unmarshl

func Unmarshal(data []byte, v interface{}) error 
type Student struct {
	Code    int         `json:"code"`    // 使用tag,表示对应json的字段名
	Message string      `json:"message"`
	Grades  []GradeType `json:"grades"`  // 结构体类数组
}
type GradeType struct {
	GradeClass string `json:"gradeClass"`
	Score      ScoreType
}
type ScoreType struct {
	Chinese int `json:"chinese"`
	English int `json:"english"`
}
func main() {
	// 这里反引号表示不转意,即为string类型
	resp := `{"code":0,"message":"success","grades":[{"gradeClass":"一年级","Score":{"chinese":99,"english":88}},{"gradeClass":"二年级","Score":{"chinese":100,"english":98}}]}`
	var stu Student
	err := json.Unmarshal([]byte(resp), &stu)
	if err != nil {
		log.Println(err)
	}
	log.Println(stu)
	// 2021/08/12 23:37:19 {0 success [{一年级 {99 88}} {二年级 {100 98}}]}
}

2.2 处理 http请求

	// http请求,得到json字符串 resp
  resp, err := http.Get("api")
  if err != nil{
    fmt.Println(err)
  }
  var stu Student
  err := json.Unmarshal([]byte(resp), &stu)
  if err != nil {
    log.Println(err)
  }
  log.Println(stu)

2.3 工具自动化生成 结构体

遇到http请求的多层嵌套json,莫慌,一键生成结构体,真香~

工具地址:https://mholt.github.io/json-to-go/

根据 定义好的 Json,自动生成结构体:

{
  "code": 0,
  "message": "success",
  "grades": [
    {
      "gradeClass": "一年级",
      "Score": {
        "chinese": 99,
        "english": 88
      }
    },
    {
      "gradeClass": "二年级",
      "Score": {
        "chinese": 100,
        "english": 98
      }
    }
  ]
}

如下:

type AutoGenerated struct {
	Code    int    `json:"code"`
	Message string `json:"message"`
	Grades  []struct {
		GradeClass string `json:"gradeClass"`
		Score      struct {
			Chinese int `json:"chinese"`
			English int `json:"english"`
		} `json:"Score"`
	} `json:"grades"`
}

3、注意点

大写