Intro
JSON 常作为 API 接口之间互动的数据编码方式。Go 内置了 JSON 库进行操作。
JSON 也为下一部分网络交互中提供了交互基础。
解析 JSON
{
"ip": "8.8.8.8",
"asn": "AS15169",
"as_name": "Google LLC",
"as_domain": "google.com",
"country_code": "US",
"country": "United States",
"continent_code": "NA",
"continent": "North America"
}以上方 JSON 为例子,开始解析。
结构
type IPInfo struct {
IP string `json:"ip"`
ASN string `json:"asn"`
ASName string `json:"as_name"`
ASDomain string `json:"as_domain"`
CountryCode string `json:"country_code"`
Country string `json:"country"`
ContinentCode string `json:"continent_code"`
Continent string `json:"continent"`
}此处可以理解为定义一种变量结构格式,在接下来的解析 JSON 的过程,就是将 JSON String 套入这个结构中。
解析 JSON 序列
假设 JSON 数据位于字符串 jsonStr:
jsonStr := `{
"ip": "8.8.8.8",
"asn": "AS15169",
"as_name": "Google LLC",
"as_domain": "google.com",
"country_code": "US",
"country": "United States",
"continent_code": "NA",
"continent": "North America"
}`
var info IPInfo
err := json.Unmarshal([]byte(jsonStr), &info)
if err != nil {
log.Fatal(err)
}这样就解析完成了,存储在 info 变量里面。
从解析的结构中读取
在此处以 fmt.Printf() 作为直接的读取方式
fmt.Printf("IP: %s, Country: %s\n", info.IP, info.Country)完整代码:
package main
import (
"encoding/json"
"fmt"
"log"
)
type IPInfo struct {
IP string `json:"ip"`
ASN string `json:"asn"`
ASName string `json:"as_name"`
ASDomain string `json:"as_domain"`
CountryCode string `json:"country_code"`
Country string `json:"country"`
ContinentCode string `json:"continent_code"`
Continent string `json:"continent"`
}
func main() {
jsonStr := `{
"ip": "8.8.8.8",
"asn": "AS15169",
"as_name": "Google LLC",
"as_domain": "google.com",
"country_code": "US",
"country": "United States",
"continent_code": "NA",
"continent": "North America"
}`
var info IPInfo
err := json.Unmarshal([]byte(jsonStr), &info)
if err != nil {
log.Fatal(err)
}
fmt.Printf("IP: %s, Country: %s\n", info.IP, info.Country)
}将 JSON 序列化
使用 json.Marshal 或 json.MarshalIndent 将结构体转换回 JSON 格式。
接下来以 Quad9 的 9.9.9.9 的 IP 地址为输出目标:
{
"ip": "9.9.9.9",
"asn": "AS19281",
"as_name": "Quad9",
"country": "USA",
"continent": "North America"
}定义结构体
上方 JSON 数据有五项,我们分别进行定义。
type IPInfo struct {
IP string `json:"ip"`
ASN string `json:"asn"`
ASName string `json:"as_name"`
Country string `json:"country"`
Continent string `json:"continent"`
}设定内容
var info IPInfo
info.IP = '9.9.9.9'
info.ASN = 'AS19281'
info.ASName = 'Quad9'
info.Country = 'USA'
info.Continent = 'North America'JSON 序列化
OutJSON, err := json.MarshalIndent(info, "", " ")
if err != nil {
log.Fatalf(err)
}这个时候就已经完成了序列化的操作。但是如果你直接 fmt.Println 会发现此时打印出来的不是 JSON 数据。
这个时候要作为字符串打印才对。
使用:
fmt.Println(string(OutJSON))这样就能打印出来了。
完整代码
package main
import (
"encoding/json"
"fmt"
)
type IPInfo struct {
IP string `json:"ip"`
ASN string `json:"asn"`
ASName string `json:"as_name"`
Country string `json:"country"`
Continent string `json:"continent"`
}
func main() {
var info IPInfo
info.IP = "9.9.9.9"
info.ASN = "AS19281"
info.ASName = "Quad9"
info.Country = "USA"
info.Continent = "North America"
OutJSON, err := json.MarshalIndent(info, "", " ")
if err != nil {
fmt.Println(err)
}
fmt.Println(string(OutJSON))
}