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

2024-06-15 03:44

本文主要是介绍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}

这篇关于20.2 JSON-JSON解码、映射数据类型、处理JSON响应的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1062340

相关文章

解决IDEA报错:编码GBK的不可映射字符问题

《解决IDEA报错:编码GBK的不可映射字符问题》:本文主要介绍解决IDEA报错:编码GBK的不可映射字符问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录IDEA报错:编码GBK的不可映射字符终端软件问题描述原因分析解决方案方法1:将命令改为方法2:右下jav

Java 中的 @SneakyThrows 注解使用方法(简化异常处理的利与弊)

《Java中的@SneakyThrows注解使用方法(简化异常处理的利与弊)》为了简化异常处理,Lombok提供了一个强大的注解@SneakyThrows,本文将详细介绍@SneakyThro... 目录1. @SneakyThrows 简介 1.1 什么是 Lombok?2. @SneakyThrows

在 Spring Boot 中实现异常处理最佳实践

《在SpringBoot中实现异常处理最佳实践》本文介绍如何在SpringBoot中实现异常处理,涵盖核心概念、实现方法、与先前查询的集成、性能分析、常见问题和最佳实践,感兴趣的朋友一起看看吧... 目录一、Spring Boot 异常处理的背景与核心概念1.1 为什么需要异常处理?1.2 Spring B

python处理带有时区的日期和时间数据

《python处理带有时区的日期和时间数据》这篇文章主要为大家详细介绍了如何在Python中使用pytz库处理时区信息,包括获取当前UTC时间,转换为特定时区等,有需要的小伙伴可以参考一下... 目录时区基本信息python datetime使用timezonepandas处理时区数据知识延展时区基本信息

MySQL 中的 JSON 查询案例详解

《MySQL中的JSON查询案例详解》:本文主要介绍MySQL的JSON查询的相关知识,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录mysql 的 jsON 路径格式基本结构路径组件详解特殊语法元素实际示例简单路径复杂路径简写操作符注意MySQL 的 J

Spring Boot中JSON数值溢出问题从报错到优雅解决办法

《SpringBoot中JSON数值溢出问题从报错到优雅解决办法》:本文主要介绍SpringBoot中JSON数值溢出问题从报错到优雅的解决办法,通过修改字段类型为Long、添加全局异常处理和... 目录一、问题背景:为什么我的接口突然报错了?二、为什么会发生这个错误?1. Java 数据类型的“容量”限制

Python Transformers库(NLP处理库)案例代码讲解

《PythonTransformers库(NLP处理库)案例代码讲解》本文介绍transformers库的全面讲解,包含基础知识、高级用法、案例代码及学习路径,内容经过组织,适合不同阶段的学习者,对... 目录一、基础知识1. Transformers 库简介2. 安装与环境配置3. 快速上手示例二、核心模

一文详解Java异常处理你都了解哪些知识

《一文详解Java异常处理你都了解哪些知识》:本文主要介绍Java异常处理的相关资料,包括异常的分类、捕获和处理异常的语法、常见的异常类型以及自定义异常的实现,文中通过代码介绍的非常详细,需要的朋... 目录前言一、什么是异常二、异常的分类2.1 受检异常2.2 非受检异常三、异常处理的语法3.1 try-

Spring 请求之传递 JSON 数据的操作方法

《Spring请求之传递JSON数据的操作方法》JSON就是一种数据格式,有自己的格式和语法,使用文本表示一个对象或数组的信息,因此JSON本质是字符串,主要负责在不同的语言中数据传递和交换,这... 目录jsON 概念JSON 语法JSON 的语法JSON 的两种结构JSON 字符串和 Java 对象互转

Python使用getopt处理命令行参数示例解析(最佳实践)

《Python使用getopt处理命令行参数示例解析(最佳实践)》getopt模块是Python标准库中一个简单但强大的命令行参数处理工具,它特别适合那些需要快速实现基本命令行参数解析的场景,或者需要... 目录为什么需要处理命令行参数?getopt模块基础实际应用示例与其他参数处理方式的比较常见问http