发起网络请求(以GET方式)

package main

import (
   "bytes"
   "encoding/json"
   "errors"
   "fmt"
   "io"
   "net/http"
)

// HttpGet
// @description 以GET方式发起网络请求
// @param url string 请求URL
// @return response []byte 请求响应结果
// @return err error 错误对象,若请求成功则为nil
func HttpGet(url string) (response []byte, err error) {
   var resp *http.Response

   // 以GET方式发起网络请求
   resp, err = http.Get(url)
   if err != nil {
      return
   }

   // 关闭网络连接
   defer func(body io.ReadCloser) {
      _ = body.Close()
   }(resp.Body)

   // 状态码非200则请求失败
   if resp.StatusCode != http.StatusOK {
      err = errors.New(resp.Status) // resp.Status 示例值:404 Not Found
      return
   }

   // 将响应体读进buffer
   buffer := bytes.NewBuffer([]byte{})
   _, err = buffer.ReadFrom(resp.Body)
   if err != nil {
      return
   }

   response = buffer.Bytes()

   return
}

func main() {
   url := "https://zj.v.api.aa1.cn/api/xz/?code=654028207203"
   // url := "https://zj.v.api.aa1.cn/api/xxx" // 测试“404 Not Found”的情况

   response, err := HttpGet(url)
   if err != nil {
      fmt.Printf("请求失败:%s", err.Error())
      return
   }

   // 请求成功会返回如下内容(JSON字符串):
   // ---------- 俺是分割线,请无视俺 ----------
   // {
   //    "code": 200,
   //    "ID": "654028207203",
   //    "msg": "查询成功,查询花费0.0002秒",
   //    "data": {
   //        "Name": "阔克托干村",
   //        "Province": "新疆维吾尔自治区",
   //        "City": "伊犁哈萨克自治州",
   //        "District": "尼勒克县",
   //        "Tow": "喀拉托别乡",
   //        "Villag": "阔克托干村",
   //        "LevelType": "5"
   //    }
   // }
   // ---------- 俺是分割线,请无视俺 ----------
   // 重要提醒①:从结果看code参数是int类型,但实际上它是float64类型,断言时要注意
   // 重要提醒②:从结果看data参数是map[string]string类型,但实际上它是map[string]any类型,断言时要注意

   // 解析响应结果,将其从JSON字符串转为map[string]any
   result := map[string]any{}
   err = json.Unmarshal(response, &result) // 注意这里是传内存地址,不是传值
   if err != nil {
      fmt.Printf("解析响应结果失败:%s", err.Error())
      return
   }

   // 检查响应结果数据格式是否正常(根据code参数是否存在来判断)
   _, exist := result["code"]
   if !exist {
      fmt.Printf("响应结果数据格式异常")
      return
   }

   // 检查错误码,其中code为200表示正常
   code, _ := result["code"].(float64) // 重要提醒:code参数是float64类型
   if code != 200 {
      fmt.Printf("请求出错:code=%.0f", code)
      return
   }

   // 检查请求是否出错,错误原因示例:查询的统计区划代码有误,请检查
   ID, _ := result["ID"].(string)   // 该参数为URL里的code参数值,若请求出错则该参数为空
   msg, _ := result["msg"].(string) // 该参数为错误原因,若无错则为“查询成功,查询花费XXX秒”
   if ID == "" {
      fmt.Printf("请求出错:msg=%s", msg)
      return
   }

   // 继续获取响应结果里的数据
   data, _ := result["data"].(map[string]any) // 重要提醒:data参数是map[string]any类型
   dataName, _ := data["Name"].(string)
   dataProvince, _ := data["Province"].(string)
   dataCity, _ := data["City"].(string)
   dataDistrict, _ := data["District"].(string)
   dataTow, _ := data["Tow"].(string)
   dataVillag, _ := data["Villag"].(string)
   dataLevelType, _ := data["LevelType"].(string)

   // 打印所有数据
   fmt.Printf("code:%.0f \n", code)                  // code:200
   fmt.Printf("ID:%s \n", ID)                        // ID:654028207203
   fmt.Printf("msg:%s \n", msg)                      // msg:查询成功,查询花费0.0002秒
   fmt.Printf("data.Name:%s \n", dataName)           // data.Name:阔克托干村
   fmt.Printf("data.Province:%s \n", dataProvince)   // data.Province:新疆维吾尔自治区
   fmt.Printf("data.City:%s \n", dataCity)           // data.City:伊犁哈萨克自治州
   fmt.Printf("data.District:%s \n", dataDistrict)   // data.District:尼勒克县
   fmt.Printf("data.Tow:%s \n", dataTow)             // data.Tow:喀拉托别乡
   fmt.Printf("data.Villag:%s \n", dataVillag)       // data.Villag:阔克托干村
   fmt.Printf("data.LevelType:%s \n", dataLevelType) // data.LevelType:5
}

Copyright © 2024 码农人生. All Rights Reserved