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

news2025/2/26 22:06:29

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 main

import (
    "encoding/json"
    "fmt"
    "log"
)

// Person with name, age and hobbies
type Person struct {
    Name    string
    Age     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 main

import (
   "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 main

import (
    "encoding/json"
    "fmt"
    "log"
)
// Types of JSON data
type Types struct {
    Boolean bool 
    Number  float64
    String  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}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1823691.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Internet Download Manager(IDM6.41)安装教程+软件安装包下载

IDM是一款多线程下载工具&#xff0c;全称InternetDownloadManager。IDM的多线程加速功能&#xff0c;能够充分利用宽带&#xff0c;所以下载速度会比较快&#xff0c;而且它支持断点续传。它的网站音视频捕获、站点抓取、静默下载等功能&#xff0c;也特别实用。 安 装 包 获 …

堆的实现及其应用

堆的概念 堆是完全二叉树&#xff0c;分为大堆和小堆。大堆&#xff1a;任何一个父亲都大于等于孩子&#xff0c;小堆&#xff1a;任何一个父亲都小于等于孩子。 堆的实现 目录 typedef int HPDataType;typedef struct Heap { HPDataType* a;int size;int capacity; }HP;//交…

java写一个验证码

生成验证码 内容&#xff1a;可以是小写字母&#xff0c;也可以是大写字母&#xff0c;还可以是数字 规则 长度为5 内容中是四位字母&#xff0c;1位数字。 其中数字只有1位&#xff0c;但是可以出现在任意的位置。 package User;import java.util.ArrayList; import jav…

MFC动态创建按钮

void CMFCApplication1Dlg::OnBnClickedOk() {for (int i 0; i < 100; i){for (int j 0; j < 100; j){CButton* pButton3 new CButton;pButton[i][j] pButton3;}}CRect rect;GetClientRect(&rect); // 获取对话框客户区的大小rect.top 10; // 设置按钮的位置rec…

【培训】企业档案管理专题(私货)

导读&#xff1a;通过该专题培训&#xff0c;可以系统了解企业档案管理是什么、为什么、怎么做。尤其是对档案的价值认知&#xff0c;如何构建与新质生产力发展相适应的企业档案工作体系将有力支撑企业新质生产力的发展&#xff0c;为企业高质量发展贡献档案力量&#xff0c;提…

02-adb的工作原理和常见命令

一、什么是adb&#xff1f; ADB 是 Android Debug Bridge 的简称&#xff0c;是 Android 平台的调试工具。通过 adb 命令可以去获取安卓设备上的一些信息&#xff0c;也可以直接操作管理 Android 模拟器或者真实的 Android 设备。 ADB 采用客户端-服务端程序架构&#xff0c;简…

12306 火车票价格解析 (PHP 解析)

1. 从接口拿数据 日期 出发站 终点站 都填上 xxx/otn/leftTicketPrice/queryAllPublicPrice?leftTicketDTO.train_date2024-06-15&leftTicketDTO.from_stationBJP&leftTicketDTO.to_stationSJP&purpose_codesADULT 返回的数据是这样的 {"validateMess…

格式工厂转换mp3失败,原因和解决方法来了

在使用格式工厂进行音频转换时&#xff0c;有时候可能会遇到转换为MP3失败的问题。这可能会让人感到困扰&#xff0c;但幸运的是&#xff0c;这样的问题通常有一些常见的原因&#xff0c;而且大多数情况下都能够轻松解决。在本文中&#xff0c;我们将探讨一些可能导致格式工厂转…

【Linux】高级IO——五种IO方式,select,poll,epoll

文章目录 一、简单了解什么是IO及五种IO模式五种IO同步IO和异步IO区别1.阻塞IO&#xff08;张三钓鱼方式&#xff09;2.非阻塞IO非阻塞轮询&#xff08;李四钓鱼方式&#xff09;使用fcntl函数实现SetNonBlock非阻塞 二、IO多路转接——select&#xff08;赵六钓鱼方式&#xf…

HTML静态网页成品作业(HTML+CSS)—— 家乡成都介绍网页(4个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有4个页面。 二、作品演示 三、代…

前端技术回顾系列 11|TS 中一些实用概念

在微信中阅读,关注公众号:CodeFit。 创作不易,如果你觉得这篇文章对您有帮助,请不要忘了 点赞、分享 和 关注 我的公众号:CodeFit,为我的持续创作提供动力。 上文回顾:泛型在类和接口中的应用 上一篇文章我们回顾了 泛型 在 类 和 接口 中的应用。 通过使用泛型,我们…

【NetTopologySuite类库】C#生成带约束(线、面)的Delaunay三角网

介绍 API地址&#xff1a;https://nettopologysuite.github.io/NetTopologySuite/api/NetTopologySuite.Triangulate.ConformingDelaunayTriangulationBuilder.html#NetTopologySuite_Triangulate_ConformingDelaunayTriangulationBuilder_Constraints 约束为线 效果图 红色…

vue代办事件案例实战练习,配有答案解析

代办事件案例 该案例&#xff0c;综合了前面所学的知识&#xff0c;列入点击事件绑定&#xff0c;双向绑定&#xff0c;v-for循环语句&#xff0c;v-model双向绑定&#xff0c;以及input标签的不同type形式。 演示代码如下&#xff1a; <template > <div id"ku…

计算机网络重要知识点

OSI 七层模型 是国际标准化组织提出的一个网络分层模型。 TCP/IP 四层模型 是目前被广泛采用的一种模型,我们可以将 TCP / IP 模型看作是 OSI 七层模型的精简版本&#xff0c;由以下 4 层组成&#xff1a; 应用层传输层网络层网络接口层 复杂的系统需要分层&#xff0c;因为每…

【Pandas】已完美解决:AttributeError: ‘DataFrame‘ object has no attribute ‘ix‘

文章目录 一、问题背景二、可能出错的原因三、错误代码示例四、正确代码示例&#xff08;结合实战场景&#xff09;五、注意事项 一、问题背景 在Pandas的早期版本中&#xff0c;ix 是一个方便的索引器&#xff0c;允许用户通过标签和整数位置来索引DataFrame的行和列。然而&a…

Go基础编程 - 05 - 数组与切片

目录 1. 数组2. 切片2.1. slice 声明、初始化2.2. slice 操作2.3. append() 追加切片、扩容2.4. 字符串和切片 3. Copy4. Array、Slice 内存布局 上一篇&#xff1a;基本类型、常量和变量 下一篇&#xff1a;指针 1. 数组 数组是同一种类型固定长度的序列&#xff08;有长度、…

新版eclipseSpringToolSuite4 get set方法自动生成注释(适用2019-03之后版本)

今天分享一个新版本eclipse 自动生成getter/setter文档注释的方法&#xff0c;看一下效果图 public class Test {//姓名private String name;/** * 获取 姓名 * return name 姓名 */public String getName() {return name;}/** * 设置 姓名 * param name 姓名 */public void …

frp55版本如何配置泛域名

大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂。 前言 之前配置的好好的frp&#xff0c;结果到用的时候不能用了&#xff0c;直接影响了我早上的一堆rss订阅源不能用&#xff0c;群里的新闻简报也没有正常推送&#xff0c;今天又翻出来捋…

SpringCloud总结(springcloud alibaba)

目录 版本说明&#xff08;很重要&#xff09; springcloud alibaba对应组件版本说明 简述 spring cloud albaba 几大模块 周会讨论 - spring cloud alibaba每周都会有周会讨论,社区活跃 spring cloud alibaba官网 注册配置中心 简单介绍 nacos 步骤 示例代码 依赖…

C# WinForm —— 35 StatusStrip 介绍

1. 简介 状态栏 StatusStrip&#xff0c;默认在软件的最下方&#xff0c;用于显示系统时间、版本、进度条、账号、角色信息、操作位置信息等 可以在状态栏中添加的控件类型有&#xff1a;StatusLabel、ProgressBar、DropDownButton、SplitButton 2. 属性 属性解释(Name)控…