当前位置: 首页 > news >正文

go编解码json和http请求

1.json概述

json是日常工作中http请求的最重要的数据格式。对比日常使用python中的json,获得http请求后json.loads和json.dumps函数,go中显的非常麻烦,这里结合json和http请求的总结下,便于积累和学习。这里给出一个json的类型,包括了数组对象等各种格式,以请求云计算的伸缩组的接口为例

{"ResponseMetadata": {"RequestId": "202504291928461ASBCDEDGSGGSBCD8A4862","Action": "DescribeScalingGroups","Version": "2020-01-01","Service": "auto_scaling","Region": "cn-beijing"},"Result": {"ScalingGroups": [{"ScalingGroupId": "scg-ydukizremqd0qsyqoc0k","ScalingGroupName": "test_create_recurrence_policy_without_end_time","LifecycleState": "Active","HealthCheckType": "ECS","VpcId": "vpc-2ff4fh7wic2dc59gp67u70mpn","SubnetIds": ["subnet-imc2pmpasbuo8gbssz4tv3cw"],"DefaultCooldown": 5,"ActiveScalingConfigurationId": "scc-ydukizstwjiq4jg1ggfy","DesireInstanceNumber": 2,"MinInstanceNumber": 0,"MaxInstanceNumber": 10,"InstanceTerminatePolicy": "OldestScalingConfigurationWithNewestInstance","ServerGroupAttributes": [],"CreatedAt": "2025-04-27T07:53:37Z","UpdatedAt": "2025-04-27T16:00:00Z","TotalInstanceCount": 2,"DBInstanceIds": [],"MultiAZPolicy": "BALANCE","LaunchTemplateId": "","LaunchTemplateVersion": "","DesireCapacityType": "units","MinSize": 0,"MaxSize": 0,"DesireCapacity": -1,"TotalCapacity": 0,"LaunchTemplateOverrides": [],"ScalingMode": "release","StoppedInstanceCount": 0,"StoppedCapacity": 0,"ProjectName": "default","Tags": [{"Key": "k1","Value": "v1"}],"LoadBalancerHealthCheckGracePeriod": 300,"InstancesDistribution": {"OnDemandBaseCapacity": 0,"OnDemandPercentageAboveBaseCapacity": 0,"CompensateWithOnDemand": false,"SpotInstanceRemedy": false},"SuspendedProcesses": []}],"NextToken": ""}
}

这个是调用DescribeScalingGroups接口查询指定ScalingGroupId参数的响应结果。这里先声明两个概念

序列化和反序列化

  • 序列化

就是将对象转化成二进制序列的过程。我们把变量从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flattening等等,都是一个意思。序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上。

  • 反序列化

就是讲二进制序列转化成对象的过程。 把变量内容从序列化的对象重新读到内存里称之为反序列化,即unpickling。

实际工作中,解析返回到JSON有三种方式:

  • 解析到结构体,使用map[string]interfance{}先接过来
  • 解析到interface,使用map[string]interface{}先接过来
  • 第三方包SimpleJSON,单纯的数据解析

上述的JSON返回数据,因为查询了指定的ScalingGroupId,希望在ScalingGroups结果判断下伸缩组的状态LifecycleState是否是Active。

查询接口DescribeScalingGroups返回的结果*output如下所示

map[ResponseMetadata:map[Action:DescribeScalingGroups Region:cn-beijing RequestId:20250429200529F297B9ADFGHJKDS96346 Service:auto_scaling Version:2020-01-01] Result:map[PageNumber:1 PageSize:10 ScalingGroups:[map[ActiveScalingConfigurationId:scc-ydukizstwjiq4jg1ggfy CreatedAt:2025-04-27T07:53:37Z DBInstanceIds:[] DefaultCooldown:5 DesireCapacity:-1 DesireCapacityType:units DesireInstanceNumber:2 HealthCheckType:ECS InstanceTerminatePolicy:OldestScalingConfigurationWithNewestInstance InstancesDistribution:map[CompensateWithOnDemand:false OnDemandBaseCapacity:0 OnDemandPercentageAboveBaseCapacity:0 SpotInstanceRemedy:false] LaunchTemplateId: LaunchTemplateOverrides:[] LaunchTemplateVersion: LifecycleState:Active LoadBalancerHealthCheckGracePeriod:300 MaxInstanceNumber:10 MaxSize:0 MinInstanceNumber:0 MinSize:0 MultiAZPolicy:BALANCE ProjectName:default ScalingGroupId:scg-ydukizremqd0qsyqoc0k ScalingGroupName:test_create_recurrence_policy_without_end_time ScalingMode:release ServerGroupAttributes:[] StoppedCapacity:0 StoppedInstanceCount:0 SubnetIds:[subnet-imc2pmpasbuo8gbssz4tv3cw] SuspendedProcesses:[] Tags:[map[Key:k1 Value:v1]] TotalCapacity:0 TotalInstanceCount:2 UpdatedAt:2025-04-27T16:00:00Z VpcId:vpc-2ff4fh7wic2dc59gp67u70mpn] map[ActiveScalingConfigurationId:scc-ydufdt2e8dd0qtlr2121 CreatedAt:2025-04-25T08:25:00Z DBInstanceIds:[] DefaultCooldown:300 DesireCapacity:-1 DesireCapacityType:units DesireInstanceNumber:-1 HealthCheckType:ECS InstanceTerminatePolicy:OldestScalingConfigurationWithOldestInstance InstancesDistribution:map[CompensateWithOnDemand:false OnDemandBaseCapacity:0 OnDemandPercentageAboveBaseCapacity:0 SpotInstanceRemedy:false] LaunchTemplateId: LaunchTemplateOverrides:[] LaunchTemplateVersion: LifecycleState:Active LoadBalancerHealthCheckGracePeriod:300 MaxInstanceNumber:1 MaxSize:0 MinInstanceNumber:1 MinSize:0 MultiAZPolicy:PRIORITY ProjectName:default ScalingGroupId:scg-ydufdqucghiq4k6pncgf ScalingGroupName:tjhs ScalingMode:recycle ServerGroupAttributes:[] StoppedCapacity:0 StoppedInstanceCount:0 SubnetIds:[subnet-imdl1ew9i03k8gbssyvxv53q] SuspendedProcesses:[] Tags:[] TotalCapacity:0 TotalInstanceCount:1 UpdatedAt:2025-04-25T08:25:59Z VpcId:vpc-imbcb3doyr5s8gbssxzkz7zt] map[ActiveScalingConfigurationId: CreatedAt:2025-04-25T08:10:17Z DBInstanceIds:[] DefaultCooldown:300 DesireCapacity:-1 DesireCapacityType:units DesireInstanceNumber:1 HealthCheckType:ECS InstanceTerminatePolicy:NewestInstance InstancesDistribution:map[CompensateWithOnDemand:false OnDemandBaseCapacity:0 OnDemandPercentageAboveBaseCapacity:0 SpotInstanceRemedy:false] LaunchTemplateId: LaunchTemplateOverrides:[] LaunchTemplateVersion: LifecycleState:InActive LoadBalancerHealthCheckGracePeriod:300 MaxInstanceNumber:100 MaxSize:0 MinInstanceNumber:0 MinSize:0 MultiAZPolicy:PRIORITY ProjectName:default ScalingGroupId:scg-ydufcse0jaiq4k3hz5nw ScalingGroupName:wxy-recycle-混合计费缩容4 ScalingMode:release ServerGroupAttributes:[] StoppedCapacity:0 StoppedInstanceCount:0 SubnetIds:[subnet-12arsfcvsqvi817q7y2rplfif] SuspendedProcesses:[] Tags:[map[Key:volc:vke:Id Value:1]] TotalCapacity:0 TotalInstanceCount:0 UpdatedAt:2025-04-25T08:10:17Z VpcId:vpc-imbcb3doyr5s8gbssxzkz7zt] map[ActiveScalingConfigurationId: CreatedAt:2025-04-25T06:08:23Z DBInstanceIds:[] DefaultCooldown:300 DesireCapacity:-1 DesireCapacityType:units DesireInstanceNumber:1 HealthCheckType:ECS InstanceTerminatePolicy:NewestInstance InstancesDistribution:map[CompensateWithOnDemand:false OnDemandBaseCapacity:0 OnDemandPercentageAboveBaseCapacity:0 SpotInstanceRemedy:false] LaunchTemplateId: LaunchTemplateOverrides:[] LaunchTemplateVersion: LifecycleState:InActive LoadBalancerHealthCheckGracePeriod:300 MaxInstanceNumber:100 MaxSize:0 MinInstanceNumber:0 MinSize:0 MultiAZPolicy:PRIORITY ProjectName:default ScalingGroupId:scg-yduf4uysvnd0qs4juwot ScalingGroupName:wxy-recycle-混合计费缩容2 ScalingMode:release ServerGroupAttributes:[] StoppedCapacity:0 StoppedInstanceCount:0 SubnetIds:[subnet-12arsfcvsqvi817q7y2rplfif] SuspendedProcesses:[] Tags:[] TotalCapacity:0 TotalInstanceCount:0 UpdatedAt:2025-04-25T06:08:23Z VpcId:vpc-imbcb3doyr5s8gbssxzkz7zt] map[ActiveScalingConfigurationId:scc-yduc64xga6d0qsvqjf7d CreatedAt:2025-04-24T02:46:41Z DBInstanceIds:[] DefaultCooldown:5 DesireCapacity:-1 DesireCapacityType:units DesireInstanceNumber:12 HealthCheckType:ECS InstanceTerminatePolicy:OldestScalingConfigurationWithOldestInstance InstancesDistribution:map[CompensateWithOnDemand:false OnDemandBaseCapacity:0 OnDemandPercentageAboveBaseCapacity:0 SpotInstanceRemedy:false] LaunchTemplateId: LaunchTemplateOverrides:[] LaunchTemplateVersion: LifecycleState:Active LoadBalancerHealthCheckGracePeriod:300 MaxInstanceNumber:100 MaxSize:0 MinInstanceNumber:0 MinSize:0 MultiAZPolicy:PRIORITY ProjectName:default ScalingGroupId:scg-yduc63lnuqiq4k6il4vh ScalingGroupName:wxy-metric-test ScalingMode:release ServerGroupAttributes:[] StoppedCapacity:0 StoppedInstanceCount:0 SubnetIds:[subnet-imdl1ew9i03k8gbssyvxv53q] SuspendedProcesses:[] Tags:[map[Key:sys Value:]] TotalCapacity:0 TotalInstanceCount:11 UpdatedAt:2025-04-28T16:00:00Z VpcId:vpc-imbcb3doyr5s8gbssxzkz7zt] map[ActiveScalingConfigurationId:scc-ydu5dwgxt1d6kr6rf3j7 CreatedAt:2025-04-21T12:11:32Z DBInstanceIds:[] DefaultCooldown:5 DesireCapacity:-1 DesireCapacityType:units DesireInstanceNumber:0 HealthCheckType:ECS InstanceTerminatePolicy:OldestScalingConfigurationWithNewestInstance InstancesDistribution:map[CompensateWithOnDemand:false OnDemandBaseCapacity:0 OnDemandPercentageAboveBaseCapacity:0 SpotInstanceRemedy:false] LaunchTemplateId: LaunchTemplateOverrides:[] LaunchTemplateVersion: LifecycleState:Active LoadBalancerHealthCheckGracePeriod:300 MaxInstanceNumber:900 MaxSize:0 MinInstanceNumber:0 MinSize:0 MultiAZPolicy:BALANCE ProjectName:default ScalingGroupId:scg-ydu5dwe4nnd6kqpbsbuc ScalingGroupName:test_e9aef648-ed16-4807-b294-3118cbb94430 ScalingMode:release ServerGroupAttributes:[] StoppedCapacity:0 StoppedInstanceCount:0 SubnetIds:[subnet-2fe72h3r8pr7k59gp68yogx1p subnet-12bhi1j0k4buo17q7y2aet40a] SuspendedProcesses:[] Tags:[] TotalCapacity:0 TotalInstanceCount:0 UpdatedAt:2025-04-25T07:34:48Z VpcId:vpc-2ff4fh7wic2dc59gp67u70mpn] map[ActiveScalingConfigurationId:scc-ydu5cvr4go7h70rs17oq CreatedAt:2025-04-21T11:55:51Z DBInstanceIds:[] DefaultCooldown:5 DesireCapacity:-1 DesireCapacityType:units DesireInstanceNumber:0 HealthCheckType:ECS InstanceTerminatePolicy:OldestScalingConfigurationWithNewestInstance InstancesDistribution:map[CompensateWithOnDemand:false OnDemandBaseCapacity:0 OnDemandPercentageAboveBaseCapacity:0 SpotInstanceRemedy:false] LaunchTemplateId: LaunchTemplateOverrides:[] LaunchTemplateVersion: LifecycleState:Active LoadBalancerHealthCheckGracePeriod:300 MaxInstanceNumber:900 MaxSize:0 MinInstanceNumber:0 MinSize:0 MultiAZPolicy:PRIORITY ProjectName:default ScalingGroupId:scg-ydu5cvobb67h7110nsqr ScalingGroupName:test_make_effort_to_provision_esi_instance_auto_scaling0 ScalingMode:release ServerGroupAttributes:[] StoppedCapacity:0 StoppedInstanceCount:0 SubnetIds:[subnet-2fe72h3r8pr7k59gp68yogx1p subnet-in29bofzzfuo8gbssxhpj6pr] SuspendedProcesses:[] Tags:[] TotalCapacity:0 TotalInstanceCount:0 UpdatedAt:2025-04-27T07:50:29Z VpcId:vpc-2ff4fh7wic2dc59gp67u70mpn] map[ActiveScalingConfigurationId: CreatedAt:2025-04-21T09:12:38Z DBInstanceIds:[] DefaultCooldown:300 DesireCapacity:-1 DesireCapacityType:units DesireInstanceNumber:0 HealthCheckType:ECS InstanceTerminatePolicy:OldestScalingConfigurationWithOldestInstance InstancesDistribution:map[CompensateWithOnDemand:false OnDemandBaseCapacity:0 OnDemandPercentageAboveBaseCapacity:0 SpotInstanceRemedy:false] LaunchTemplateId:lt-ydu521mjhd4pf5w7iffd LaunchTemplateOverrides:[] LaunchTemplateVersion:Default LifecycleState:InActive LoadBalancerHealthCheckGracePeriod:300 MaxInstanceNumber:900 MaxSize:0 MinInstanceNumber:0 MinSize:0 MultiAZPolicy:PRIORITY ProjectName:default ScalingGroupId:scg-ydu529hknc7h711wnzt7 ScalingGroupName:任华西-esi-segmented ScalingMode:release ServerGroupAttributes:[] StoppedCapacity:0 StoppedInstanceCount:0 SubnetIds:[subnet-in29bofzzfuo8gbssxhpj6pr] SuspendedProcesses:[] Tags:[] TotalCapacity:0 TotalInstanceCount:0 UpdatedAt:2025-04-21T09:12:38Z VpcId:vpc-2ff4fh7wic2dc59gp67u70mpn] map[ActiveScalingConfigurationId: CreatedAt:2025-04-21T09:03:03Z DBInstanceIds:[] DefaultCooldown:5 DesireCapacity:-1 DesireCapacityType:units DesireInstanceNumber:0 HealthCheckType:ECS InstanceTerminatePolicy:OldestScalingConfigurationWithOldestInstance InstancesDistribution:map[CompensateWithOnDemand:false OnDemandBaseCapacity:0 OnDemandPercentageAboveBaseCapacity:0 SpotInstanceRemedy:false] LaunchTemplateId:lt-ydt96663gx4pf62xh0w1 LaunchTemplateOverrides:[] LaunchTemplateVersion:Default LifecycleState:Active LoadBalancerHealthCheckGracePeriod:300 MaxInstanceNumber:900 MaxSize:0 MinInstanceNumber:0 MinSize:0 MultiAZPolicy:BALANCE ProjectName:default ScalingGroupId:scg-ydu51n3ag57h71541h5j ScalingGroupName:test_make_effort_to_provision_esi_instance_with_modify_policy_auto_scaling0 ScalingMode:release ServerGroupAttributes:[] StoppedCapacity:0 StoppedInstanceCount:0 SubnetIds:[subnet-in29bofzzfuo8gbssxhpj6pr] SuspendedProcesses:[] Tags:[] TotalCapacity:0 TotalInstanceCount:0 UpdatedAt:2025-04-22T07:14:04Z VpcId:vpc-2ff4fh7wic2dc59gp67u70mpn] map[ActiveScalingConfigurationId:scc-ydtx5nu76w7h70wslv7c CreatedAt:2025-04-18T08:16:10Z DBInstanceIds:[] DefaultCooldown:5 DesireCapacity:-1 DesireCapacityType:units DesireInstanceNumber:0 HealthCheckType:ECS InstanceTerminatePolicy:NewestInstance InstancesDistribution:map[CompensateWithOnDemand:false OnDemandBaseCapacity:0 OnDemandPercentageAboveBaseCapacity:0 SpotInstanceRemedy:false] LaunchTemplateId: LaunchTemplateOverrides:[] LaunchTemplateVersion: LifecycleState:Active LoadBalancerHealthCheckGracePeriod:300 MaxInstanceNumber:10 MaxSize:0 MinInstanceNumber:0 MinSize:0 MultiAZPolicy:BALANCE ProjectName:default ScalingGroupId:scg-ydtx5nssrpd6ksegkwyp ScalingGroupName:test_create_alarm_policy_and_specify_effective_time_auto_scaling0 ScalingMode:release ServerGroupAttributes:[] StoppedCapacity:0 StoppedInstanceCount:0 SubnetIds:[subnet-imc2pmpasbuo8gbssz4tv3cw] SuspendedProcesses:[] Tags:[] TotalCapacity:0 TotalInstanceCount:0 UpdatedAt:2025-04-21T06:05:49Z VpcId:vpc-2ff4fh7wic2dc59gp67u70mpn]] TotalCount:19]]

如果通过如下“美化”,可以输出到按照最初给出实例一样展示出来

	jsonData, _ := json.MarshalIndent(output, "", "  ")fmt.Println(string(jsonData))

json.MarshalIndent(output, "", " ")

  • 将 Go 的结构体(或任意可序列化的值)output 转换成 格式化后的 JSON 字符串

  • 第二个参数是前缀(通常设为 ""),第三个参数是每层缩进的字符串(这里是两个空格 " ")。

  • 返回的是一个 []byte 类型的 JSON 数据。

  • 将[]byte类型的JSON数据转换成go中的string类型,方便控制台输出用于调试。

json.MarshalIndent(...) + Println打印结构,用于调试

2.完全解析到结构体

参考上面的JSON响应,我们需要定义与之对应的结构体

// ResponseMetadata 定义响应元数据部分
type ResponseMetadata struct {Action    string `json:"Action"`Region    string `json:"Region"`RequestId string `json:"RequestId"`Service   string `json:"Service"`Version   string `json:"Version"`
}// InstancesDistribution 定义实例分布信息
type InstancesDistribution struct {CompensateWithOnDemand              bool `json:"CompensateWithOnDemand"`OnDemandBaseCapacity                int  `json:"OnDemandBaseCapacity"`OnDemandPercentageAboveBaseCapacity int  `json:"OnDemandPercentageAboveBaseCapacity"`SpotInstanceRemedy                  bool `json:"SpotInstanceRemedy"`
}// Tag 定义标签信息
type Tag struct {Key   string `json:"Key"`Value string `json:"Value"`
}// ScalingGroup 定义伸缩组信息
type ScalingGroup struct {ActiveScalingConfigurationId       string                `json:"ActiveScalingConfigurationId"`CreatedAt                          string                `json:"CreatedAt"`DBInstanceIds                      []string              `json:"DBInstanceIds"`DefaultCooldown                    int                   `json:"DefaultCooldown"`DesireCapacity                     int                   `json:"DesireCapacity"`DesireCapacityType                 string                `json:"DesireCapacityType"`DesireInstanceNumber               int                   `json:"DesireInstanceNumber"`HealthCheckType                    string                `json:"HealthCheckType"`InstanceTerminatePolicy            string                `json:"InstanceTerminatePolicy"`InstancesDistribution              InstancesDistribution `json:"InstancesDistribution"`LaunchTemplateId                   string                `json:"LaunchTemplateId"`LaunchTemplateOverrides            []interface{}         `json:"LaunchTemplateOverrides"`LaunchTemplateVersion              string                `json:"LaunchTemplateVersion"`LifecycleState                     string                `json:"LifecycleState"`LoadBalancerHealthCheckGracePeriod int                   `json:"LoadBalancerHealthCheckGracePeriod"`MaxInstanceNumber                  int                   `json:"MaxInstanceNumber"`MaxSize                            int                   `json:"MaxSize"`MinInstanceNumber                  int                   `json:"MinInstanceNumber"`MinSize                            int                   `json:"MinSize"`MultiAZPolicy                      string                `json:"MultiAZPolicy"`ProjectName                        string                `json:"ProjectName"`ScalingGroupId                     string                `json:"ScalingGroupId"`ScalingGroupName                   string                `json:"ScalingGroupName"`ScalingMode                        string                `json:"ScalingMode"`ServerGroupAttributes              []interface{}         `json:"ServerGroupAttributes"`StoppedCapacity                    int                   `json:"StoppedCapacity"`StoppedInstanceCount               int                   `json:"StoppedInstanceCount"`SubnetIds                          []string              `json:"SubnetIds"`SuspendedProcesses                 []interface{}         `json:"SuspendedProcesses"`Tags                               []Tag                 `json:"Tags"`TotalCapacity                      int                   `json:"TotalCapacity"`TotalInstanceCount                 int                   `json:"TotalInstanceCount"`UpdatedAt                          string                `json:"UpdatedAt"`VpcId                              string                `json:"VpcId"`
}// Result 定义结果部分
type Result struct {PageNumber    int            `json:"PageNumber"`PageSize      int            `json:"PageSize"`ScalingGroups []ScalingGroup `json:"ScalingGroups"`
}// Response 定义整个响应结构
type Response struct {ResponseMetadata ResponseMetadata `json:"ResponseMetadata"`Result           Result           `json:"Result"`
}

使用上面的结构体查询并遍历最终的结果

func DescribeScalingGroups(session *session.Session) {// 构建自定义GET请求universalReq := universal.RequestUniversal{ServiceName: "auto_scaling",Action:      "DescribeScalingGroups",Version:     "2020-01-01",HttpMethod:  universal.GET,}// 创建自定义GET客户端universal := universal.New(session)// 目标 ScalingGroupIdtargetId := "scg-ydu51n3ag57h71541h5j"// 指定参数形式parameters := map[string]interface{}{"ScalingGroupIds.1": targetId,}output, err := universal.DoCall(universalReq, &parameters)if err != nil {panic(err)}fmt.Println(*output)// 假设 output 是从 DoCall 返回的 *Response 类型// jsonData, _ := json.MarshalIndent(output, "", "  ")// fmt.Println(string(jsonData))// 将 output 映射到 Response 结构体var resp Responsedata, err := json.Marshal(output) // 将output 转换为 JSON 格式的字节流([]byte)if err != nil {panic(err)}err = json.Unmarshal(data, &resp) // 使用 json.Unmarshal 函数将上述得到的 JSON 字节流反序列化到 resp 变量中if err != nil {fmt.Println("Error unmarshalling JSON:", err)return}// 查找并打印 LifecycleStatefor _, group := range resp.Result.ScalingGroups {if group.ScalingGroupId == targetId {fmt.Printf("ScalingGroupId %s has LifecycleState: %s\n", targetId, group.LifecycleState)return}}fmt.Printf("ScalingGroupId %s not found.\n", targetId)}

3.简化解析到结构体

我们发现我们只需要比如ScalingGroupId和LifecycleState,甚至是部分的Metadata元数据,其他的很多数据都不需要使用,“感觉”没有必要定义。这个感觉是对的,很多语言就是这样,编程语言是面向人的,给机器使用的。

// ResponseMetadata 定义响应元数据部分,如果不需要可以省略或简化
type ResponseMetaData struct {Action  string `json:"Action"`Region  string `json:"Region"`Request string `json:"Request"`
}// ScalingGroup,只定义需要的字段
type ScalingGroup struct {ScalingGroupId string `json:"ScalingGroupId"`LifecycleState string `json:"LifecycleState"`
}// 定义结果部分
type Result struct {ScalingGroups []ScalingGroup `json:"ScalingGroups"`
}// 定义整个响应结构
type Response struct {ResponseMetaData ResponseMetaData `json:"ResponseMetaData"`Result           Result           `json:"Result"`
}

封装查询接口

func DescribeScalingGroups(session *session.Session) {// 构建自定义GET请求universalReq := universal.RequestUniversal{ServiceName: "auto_scaling",Action:      "DescribeScalingGroups",Version:     "2020-01-01",HttpMethod:  universal.GET,}// 创建自定义GET客户端universal := universal.New(session)// 发起请求并处理返回或异常parameters := make(map[string]interface{})output, err := universal.DoCall(universalReq, &parameters)if err != nil {panic(err)}fmt.Println(*output)// 假设 output 是从 DoCall 返回的 *Response 类型// jsonData, _ := json.MarshalIndent(output, "", "  ")// fmt.Println(string(jsonData))// 将 output 映射到 Response 结构体var resp Responsedata, err := json.Marshal(output) // 将output 转换为 JSON 格式的字节流([]byte)if err != nil {panic(err)}err = json.Unmarshal(data, &resp) // 使用 json.Unmarshal 函数将上述得到的 JSON 字节流反序列化到 resp 变量中if err != nil {fmt.Println("Error unmarshalling JSON:", err)return}// 目标 ScalingGroupIdtargetId := "scg-ydu51n3ag57h71541h5j"// 查找并打印 LifecycleStatefor _, group := range resp.Result.ScalingGroups {if group.ScalingGroupId == targetId {fmt.Printf("ScalingGroupId %s has LifecycleState: %s\n", targetId, group.LifecycleState)return}}fmt.Printf("ScalingGroupId %s not found.\n", targetId)}

4.解析到interface

我们知道Interface{}可以用来存储任何类型的对象,这样数据结构正好可以存储解析繁琐嵌套的JSON结果,JSON包中采用的map[string]interface{}和[]interface{}结构来存储任意的JSON对象和数组。所以任何结构我们都可以定义并解析到Interface{}里面

response := []byte(`{"RequestId":"202504291928461ADFGHJKCD8A4862","Action":"DescribeScalingGroups","ScalingGroups":["scalingGroupId1","scalingGroupId2"]}`)var f interface{}
err := json.Unmarshal{response, &b}

这个时候f里面就存储了一个map类型,他们的key是string,值存储在空的interface{}中的

f = map[string]interface{}{"RequestId":"202504291928461ADFGHJKCD8A4862","Action":"DescribeScalingGroups","ScalingGroups":[]interface{}{"scalingGroupId1","scalingGroupId2",},
}

那如何来访问需要的LifecycleState字段呢,可以通过断言的方式

m := f.(map[string]interface{})

接着给出示例

func DescribeScalingGroups(session *session.Session) {// 构建自定义GET请求universalReq := universal.RequestUniversal{ServiceName: "auto_scaling",Action:      "DescribeScalingGroups",Version:     "2020-01-01",HttpMethod:  universal.GET,}// 创建自定义GET客户端universal := universal.New(session)// 发起请求并处理返回或异常parameters := make(map[string]interface{})output, err := universal.DoCall(universalReq, &parameters)if err != nil {panic(err)}fmt.Println(*output)// 假设 output 是从 DoCall 返回的 *Response 类型// jsonFormateData, _ := json.MarshalIndent(output, "", "  ")// fmt.Println(string(jsonFormateData))// 查找并打印 LifecycleStatejsonData, err := json.Marshal(output) // 将output 转换为 JSON 格式的字节流([]byte)if err != nil {panic(err)}var x interface{}err = json.Unmarshal(jsonData, &x)if err != nil {fmt.Println("Error unmarshalling JSON:", err)return}fmt.Println("x contains: ", x)fmt.Println("===============")// 类型断言为 map[string]interface{}m := x.(map[string]interface{})// 访问 Result 下的 ScalingGroupsresult := m["Result"].(map[string]interface{})scalingGroups := result["ScalingGroups"].([]interface{})// 目标 ScalingGroupIdtargetId := "scg-ydu51n3ag57h71541h5j"// 查找并打印 LifecycleStatefor _, item := range scalingGroups {group := item.(map[string]interface{})scalingGroupId := group["ScalingGroupId"].(string)lifecycleState := group["LifecycleState"].(string)if scalingGroupId == targetId {fmt.Printf("ScalingGroupId %s has LifecycleState: %s\n", targetId, lifecycleState)return}}fmt.Printf("ScalingGroupId %s not found.\n", targetId)}

4.使用第三方包SimpleJSON

既然要使用第三方的包,需要先安装

go get "github.com/bitly/go-simplejson"

这里直接给出示例

func DescribeScalingGroups(session *session.Session) {// 构建自定义GET请求universalReq := universal.RequestUniversal{ServiceName: "auto_scaling",Action:      "DescribeScalingGroups",Version:     "2020-01-01",HttpMethod:  universal.GET,}// 创建自定义GET客户端universal := universal.New(session)// 发起请求并处理返回或异常parameters := make(map[string]interface{})output, err := universal.DoCall(universalReq, &parameters)if err != nil {panic(err)}fmt.Println(*output)// 假设 output 是从 DoCall 返回的 *Response 类型// jsonData, _ := json.MarshalIndent(output, "", "  ")// fmt.Println(string(jsonData))// 查找并打印 LifecycleStatedata, err := json.Marshal(output) // 将output 转换为 JSON 格式的字节流([]byte)if err != nil {panic(err)}// Step 2: 用 simplejson 解析simpleJsonData, err := simplejson.NewJson(data)if err != nil {fmt.Println("Failed to parse JSON:", err)return}// Step 3: 查找目标 ScalingGroupIdtargetId := "scg-ydu51n3ag57h71541h5j"scalingGroups, err := simpleJsonData.Get("Result").Get("ScalingGroups").Array()if err != nil {fmt.Println("Error getting ScalingGroups array:", err)return}for _, item := range scalingGroups {group := item.(map[string]interface{})scalingGroupId := group["ScalingGroupId"].(string)lifecycleState := group["LifecycleState"].(string)if scalingGroupId == targetId {fmt.Printf("Found LifecycleState: %s\n", lifecycleState)return}}}

5.编解码

5.1 Marshal*

上文中看到了Marshal()和MarshalIndent()函数可以将数据封装成json数据。

  • struct、slice、array、map都可以转换成json
  • struct转换成json的时候,只有字段首字母大写的才会被转换
  • map转换的时候,key必须为string
  • 封装的时候,如果是指针,会追踪指针指向的对象进行封装

先有数据结构,然后Marshal。JSON包里Marshal函数来处理,函数定义如下:

func Marshal(v interface{}) ([]byte, error)
package mainimport ("encoding/json""fmt"
)type Server struct {ServerName stringServerIP   string
}type Serverslice struct {Servers []Server
}func main() {var s Serverslices.Servers = append(s.Servers, Server{ServerName: "ecs", ServerIP: "127.0.0.1"})s.Servers = append(s.Servers, Server{ServerName: "auto_scaling", ServerIP: "127.0.0.2"})b, err := json.Marshal(s)if err != nil {fmt.Println("json err:", err)}fmt.Println(string(b))
}

输出结果如下所示:

{"Servers":[{"ServerName":"ecs","ServerIP":"127.0.0.1"},{"ServerName":"auto_scaling","ServerIP":"127.0.0.2"}]}

5.2 json.NewEncoder和json.NewDecoder

除了marshal和unmarshal函数,Go还提供了Decoder和Encoder对streamJSON进行处理,常见 request中的Body、文件等。

// 编码
json.NewEncoder(<Writer>).encode(v)
json.Marshal(&v)// 解码
json.NewDecoder(<Reader>).decode(&v)
json.Unmarshal([]byte, &v)

5.3 Marshal vs jons.New*coder

package mainimport ("encoding/json""fmt""bytes""strings"
)type Person struct {Name string `json:"name"`Age int `json:"age"`
}func main()  {// 1. 使用 json.Marshal 编码person1 := Person{"zhangsan", 35}bytes1, err := json.Marshal(&person1)if err == nil {// 返回的是字节数组 []bytefmt.Println("json.Marshal 编码结果: ", string(bytes1))}// 2. 使用 json.Unmarshal 解码str := `{"name":"lisi","age":35}`// json.Unmarshal 需要字节数组参数, 需要把字符串转为 []byte 类型bytes2 := []byte(str) // 字符串转换为字节数组var person2 Person    // 用来接收解码后的结果if json.Unmarshal(bytes2, &person2) == nil {fmt.Println("json.Unmarshal 解码结果: ", person2.Name, person2.Age)}// 3. 使用 json.NewEncoder 编码person3 := Person{"wangwu", 35}// 编码结果暂存到 bufferbytes3 := new(bytes.Buffer)_ = json.NewEncoder(bytes3).Encode(person3)if err == nil {fmt.Print("json.NewEncoder 编码结果: ", string(bytes3.Bytes()))}// 4. 使用 json.NewDecoder 解码str4 := `{"name":"lier","age":34}`var person4 Person// 创建一个 string reader 作为参数err = json.NewDecoder(strings.NewReader(str4)).Decode(&person4)if err == nil {fmt.Println("json.NewDecoder 解码结果: ", person4.Name, person4.Age)}
}

相关文章:

  • 时序数据库 TDengine × Perspective:你需要的可视化“加速器”
  • 仿腾讯会议——注册登录UI
  • 数据库系统概论|第三章:关系数据库标准语言SQL—课程笔记7
  • Android Framework常见问题
  • 并发设计模式实战系列(9):消息传递(Message Passing)
  • 废品回收小程序:全链路数字化解决方案,赋能绿色未来
  • TDengine 订阅不到数据问题排查
  • unity在编辑器模式调试音频卡顿电流声
  • 10.学习笔记-MyBatisPlus(P105-P110)
  • 水库现代化建设指南-水库运管矩阵管理系统建设方案
  • Android WIFI体系
  • Liunx安装Apache Tomcat
  • 数据一致性巡检总结:基于分桶采样的设计与实现
  • Linux CentOS 7 安装Apache 部署html页面
  • 松下机器人快速入门指南(2025年更新版)
  • python:sklearn 决策树(Decision Tree)
  • 当前HPLC载波无法满足全量数据分钟级采集需求的主要原因
  • 绿色版的notepad++怎么加入到右键菜单里
  • 深挖Java基础之:认识Java(创立空间/先导:Java认识)
  • 【Linux】第十四章 提高命令行效率
  • 深圳一季度GDP为8950.49亿元,同比增长5.2%
  • 解放日报头版头条:“五个中心”蹄疾步稳谱新篇
  • 人民时评:投资于人,促高质量充分就业
  • 大家聊中国式现代化|邓智团:践行人民城市理念,开创人民城市建设新局面
  • 体坛联播|皇马上演罢赛闹剧,杨瀚森宣布参加NBA选秀
  • 明查|把太平洋垃圾污染问题甩锅中国,特朗普用的是P过的图