您的位置:首页 > 游戏 > 手游 > 20.2 JSON-JSON解码、映射数据类型、处理JSON响应

20.2 JSON-JSON解码、映射数据类型、处理JSON响应

2024/10/6 8:40:19 来源:https://blog.csdn.net/AlieNeny/article/details/139640738  浏览:    关键词:20.2 JSON-JSON解码、映射数据类型、处理JSON响应

1. JSON解码

JSON解码,即将JSON格式在字符串转换为Go语言数据类型的变量。

函数Unmarshal接受一个JSON字节切片和一个指定目标格式的接口。而这个借口即与JSON字符串中的结果相匹配的结构体类型的变量

  • 定义结构体类型
    • type Person struct { ... }
  • 创建结构体变量
    • p := Person{}
  • 将JSON格式的字符串转换JSON格式的字节切片
    • jb := []byte(js) 
  • 将JSON格式的字节切片解码为结构体变量
    • err := json.Unmarshal(jb, &p)

// 将JSON字符解码为结构体
//             []byte               json.Unmarshal 
// JSON字符串 ------> JSON字节切片 --------------> 结构体
package mainimport ("encoding/json""fmt""log"
)// Person with name, age and hobbies
type Person struct {Name    stringAge     int Hobbies []string
}func main() {js := `{"Name":"George","Age":40,"Hobbies":["Cycling","Cheese","Techno"]}`fmt.Println(js)jb := []byte(js)	// 将json字符串转化为字节切片p := Person{}	// json目标对象接口err := json.Unmarshal(jb, &p)if err != nil {log.Fatal(err)}fmt.Printf("%+v\n", p)
}
// 打印输出:
{"Name":"George","Age":40,"Hobbies":["Cycling","Cheese","Techno"]}
{Name:George Age:40 Hobbies:[Cycling Cheese Techno]} 

默认情况下,JSON字符串中的分别映射结构体中的字段名字段值(大小写敏感)。

  • {"Name":"George","Age":40,"Hobbies":["Cycling","Cheese","Techno"]}
  • type Person struct {
  •     Name    string
  •     Age     int
  •     Hobbies []string
  • }

如果为结构体字段指定了JSON标签,则以标签文本对应JSON字符串的键。

  • {"name":"George","age":40,"hobbies":["Cycling","Cheese","Techno"]}
  • type Person struct {
  •     Name    string   `json:"name"`
  •     Age     int      `json:"age"`
  •     Hobbies []string `json:"hobbies"`
  • }
// 映射JSON键到结构体字段
// 默认情况下,JSON字符串中的键和值分别映射结构体中的字段名和字段值,但
// 如果为结构体中的字段指定了JSON标签,则以标签文本对应JSON字符串的键
// 
// type 结构体 struct {
//     字段1 类型1 `json:"键1"` 
//     字段2 类型2 `json:"键2"` 
//     ... 
//     字段n 类型n `json:"键n"`
// }
package mainimport ("encoding/json""fmt""log""testing"
)
// Person with name, age and hobbies
type Person4 struct {Name    string   `json:"MyName"`Age     int      `json:"MyAge"`Hobbies []string `json:"MyHobbies"`
}func TestJson2Struct2(t *testing.T) {js := `{"MyName":"George","MyAge":40,"MyHobbies":["Cycling","Cheese","Techno"]}`fmt.Println(js)jb := []byte(js)p := Person4{}err := json.Unmarshal(jb, &p)if err != nil {log.Fatal(err)}fmt.Printf("%+v\n", p)
}
// 打印输出:
{"name":"George","age":40,"hobbies":["Cycling","Cheese","Techno"]}
{Name:George Age:40 Hobbies:[Cycling Cheese Techno]}

 2. 映射数据类型

Go是一种强类型语言,而JavaScript是一种弱类型语言encoding/json包根据以下所列规则,在两种语言的类型系统之间进行显式类型转换。

JSON

Go

Boolean

bool

Number

float64

String

string

Array

[]interface{}(切片类型)

Object

map[string]interface{}

(映射类型)

Null

nil

js := `{

    "Boolean" : false,

    "Number"  : 4,

    "String"  : "Helo World!",

    "Array"   : [1, 2, 3, 4, 5],

    "Object"  : {"MON": 1, "TUE": 2, "WED": 3, "THU": 4, "FRI": 5},

    "Null"    : null

    }`

type Types struct {

    Boolean bool

    Number  float64

    String  string

    Array   []int

    Object  map[string]int

    Null    *int

   }

// JSON的数据类型
// JSON的数据类型与Go的数据类型存在如下对应关系: 
//
// +--------------+------------------------+
// |     JSON     |           Go           |
// +--------------+------------------------+
// | Boolean      | bool                   |
// | Number       | float64                |
// | String       | string                 |
// | Array        | []interface{}          |
// | Object       | map[string]interface{} |
// | Null         | nil                    |
// +--------------+------------------------+
package mainimport ("encoding/json""fmt""log"
)
// Types of JSON data
type Types struct {Boolean bool Number  float64String  string Array   []int Object  map[string]int Null    *int 
} func main() {js := `{"Boolean" : false,"Number"  : 4,"String"  : "Helo World!","Array"   : [1, 2, 3, 4, 5],"Object"  : {"MON": 1, "TUE": 2, "WED": 3, "THU": 4, "FRI": 5},"Null"    : null
}`fmt.Println(js)jb := []byte(js)t := Types{}err := json.Unmarshal(jb, &t)if err != nil {log.Fatal(err)}fmt.Printf("%+v\n", t)
} 
// 打印输出:
{"Boolean" : false,"Number"  : 4,"String"  : "Helo World!","Array"   : [1, 2, 3, 4, 5],"Object"  : {"MON": 1, "TUE": 2, "WED": 3, "THU": 4, "FRI": 5},"Null"    : null
}
{Boolean:false Number:4 String:Helo World! Array:[1 2 3 4 5] Object:map[MON:1 TUE:2 WED:3 THU:4 FRI:5] Null:<nil>}

 3. 处理JSON响应

在Go语言中,通过标准库net/http包的Get函数获取到的HTTP响应是一个输入流(实现了io.Reader接口),而非字符串或字节切片。其中JSON格式的数据无法直接通过encoding/json包的Unmarshal函数解码为结构体变量,需先转化为字节切片。

调用encoding/json包的NewDecoder函数可以创建一个JSON解码器。该解码器将其被创建时传入的输入流作为数据源,并通过Decode方法将数据源中的JSON数据解码为结构体变量,借助该方法的参数输出给调用者。

  • type User struct { ... }
  • response, err := http.Get("https://api.github.com/users/shapeshed")
  • decoder, user := json.NewDecoder(response.Body), User{}返回解码器对象decoder,解码器具备了对json格式响应的读取能力;
  • err = decoder.Decode(&user) // 解码并填写user结构体的字段
// 解析JSON格式的API返回值
// 响应 = http.Get(API的URL)
// 解码器 = json.NewDecoder(响应体)
// 解码器.Decode(&结构体)
package main
import ("encoding/json""fmt""log""net/http"
)
// User of Github 
type User struct {Name string `json:"name"`Blog string `json:"blog"`
}func main() {    response, err := http.Get( // 获取response"https://api.github.com/users/shapeshed")if err != nil {log.Fatal(err)}defer response.Body.Close()decoder, user := json.NewDecoder(response.Body), User{}err = decoder.Decode(&user)if err != nil {log.Fatal(err)}fmt.Printf("%+v\n", user)
}
// 打印输出:
{Name:George Ornbo Blog:http://shapeshed.com}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com