<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      導航

      Go Http Get 和 Post 工具函數

      前言

      先說一下為什么要搞這個小東西?

      米攸服務端前期主要是基于 Go 構建的,版本迭代過程中,業務復雜度不斷增加,再加上中員團隊有人員變動,考慮到目前團隊的技術背景,我們開始考慮把接口服務分批遷移到 Java,開發效率和可控程度更高一些。其中有一些接口服務涉及周邊模塊較多,遷移的時間成本較高,我們決定暫時繼續維護這些接口。后續接口需要升級時,如果變動較小,我們直接修改 Go 代碼;如果變動較大,我們在 Go 代碼中使用 HTTP 的方式調用 Java 接口實現,相當于給原有接口加了一個 鉤子。為了減化接口調用代碼編寫的復雜度,我們考慮在 Go 代碼中內置兩個工具函數:GetPost,方便調用 Java 接口。

      本文重點討論 Get 和 Post 函數實現的關鍵細節,并給出核心代碼。

      Result

      Java 接口的返回結果是一個 固定格式Json 字符串:

      • id

        請求ID,字符串。

      • code

        狀態碼,整數。

      • msg

        狀態信息,字符串。

      • data

        數據,任意類型。

      我們使用 結構體 封裝返回結果:

        type Result struct {
          Id   string      `json:"id"`
          Code int         `json:"code"`
          Msg  string      `json:"msg"`
          Data interface{} `json:"data"`
        }
      

      可以發現,結構體的字段名稱和返回結果的字段名稱是不一樣的(首字母大小寫),兩者相互轉換的時候名稱會對應不上,需要在結構體中使用類似 `json:"id"` 的聲明,把結構體中的字段名稱和返回結果的字段名稱一一對應起來。

      特別注意:聲明字段名稱時標點符號的使用。

      Client

      Go 提供的 Http 客戶端(Client)實例是線程安全的,一個進程內只需要有一個即可:

        var client = http.Client{}
      

      Get

      Get 函數的參數應該有兩個:接口路徑(url)和 接口參數(params)。接口路徑比較簡單,就是一個字符串(string),我們主要討論接口參數。

      我們使用 Query String 的方式傳遞 Get 參數,如:/interface/param1=value1&param2=value2,接口參數的類型應該是一個內部包含多個鍵值對的 字典(map[string]interface{}),鍵名稱是參數名稱,鍵值是參數值;考慮到實際使用場景,參數值的類型限制為三種:

      • string
      • int
      • float64

      因為參數的值類型是不確定的,所以使用 interface{} 表示任意類型,函數內部判斷具體類型。

      因為調用接口時需要添加 請求頭請求參數,所以不能直接使用 http.Get 這樣的簡化函數,實現流程:

      創建請求

      使用 http.NewRequest 創建請求:

        req, err := http.NewRequest("GET", url, nil) 
      

      添加請求頭

      設置請求響應的內容類型為 json:

        req.Header.Add("Content-Type", "application/json")
      

      設置調用接口時的 Token:

        req.Header.Add("token", MEETU_API_TOKEN) 
      

      添加請求參數

      創建請求參數:

        query := req.URL.Query() 
      

      逐個添加請求參數:

       query.Add(name, value) 
      

      注意:添加請求參數時,name(參數名稱) 和 value(參數類型) 類型都是字符串。

      如前文所述,接口參數是一個字典類型的變量,我們需要遍歷這個變量中的每一個鍵值對,逐個添加參數。遍歷可以使用 Range

        for name, value := range params {
          ...
        }
      

      如前文所述,參數值類型是有限制的,遍歷過程中,我們需要判斷參數值類型是否符合要求。類型判斷可以使用 value.(type)

        switch value.(type) {
        case string:
          query.Add(name, value.(string))
      
        case int:
          query.Add(name, strconv.Itoa(value.(int)))
      
        case float64:
          query.Add(name, strconv.FormatFloat(value.(float64), 'f', -1, 64))
      
        default:
          return Result{}, errors.New("params type only support string, int and float64")
        }
      

      使用 value.(string)、value.(int) 和 value.(float64) 把變量 value(類型:interface{}) 分別轉換為類型 string、int 和 float64 的變量。使用 strconv.Itoa 把 int 變量轉換為 string 變量,使用 strconv.FormatFloat 把 float64 變量轉換為 string 變量。

      請求參數值可能包含特殊字符,需要轉義:

        req.URL.RawQuery = query.Encode()
      

      請求參數添加完成。

      執行請求,獲取結果

        resp, err := client.Do(req)
      
        defer resp.Body.Close()
      

      defer 表示 Get 函數執行完成之后,關閉 Http 客戶端內部的網絡連接。

      解析結果

      響應體(resp.Body)的數據是字節流,需要解碼并反序列化成類型為 Result 的變量 result:

        json.NewDecoder(resp.Body).Decode(&result)
      

      返回結果

        return result, nil 
      

      到此,Get 函數實現完成,代碼如下:

        func Get(url string, params map[string]interface{}) (Result, error) {
          req, err := http.NewRequest("GET", url, nil)
          if err != nil {
            return Result{}, err
          }
      
          req.Header.Add("Content-Type", "application/json")
          req.Header.Add("token", MEETU_API_TOKEN)
      
          if params != nil {
            query := req.URL.Query()
      
            for name, value := range params {
              switch value.(type) {
              case string:
                query.Add(name, value.(string))
      
              case int:
                query.Add(name, strconv.Itoa(value.(int)))
      
              case float64:
                query.Add(name, strconv.FormatFloat(value.(float64), 'f', -1, 64))
      
              default:
                return Result{}, errors.New("params type only support string, int and float64")
              }
            }
      
            req.URL.RawQuery = query.Encode()
          }
      
          resp, err := client.Do(req)
          if err != nil {
            return Result{}, err
          }
      
          defer resp.Body.Close()
      
          var result Result
      
          err = json.NewDecoder(resp.Body).Decode(&result)
          if err != nil {
            return Result{}, err
          }
      
          return result, nil
        }
      

      Post

      Post 函數的實現過程整體和 Get 是類似的,唯一不同的就是請求參數的處理。我們使用 Body 傳遞 Post 參數。

      其余內容請參考:Go Http Get 和 Post 工具函數

      posted on 2022-05-12 09:45  非著名野生程序員  閱讀(785)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 韩国免费a级毛片久久| 国产极品尤物粉嫩在线观看| 亚洲精品综合一区二区三区| 亚洲国产日韩在线视频| 亚洲成av人片无码天堂下载| 东京热tokyo综合久久精品| 亚洲AV国产福利精品在现观看| 国产精品一区二区无线| 人妻系列中文字幕精品| 国产自拍在线一区二区三区| 夜夜高潮次次欢爽av女| 开心一区二区三区激情| 性欧美三级在线观看| 国产做无码视频在线观看| 和静县| 日韩亚洲国产激情一区二区| 成人网站免费观看永久视频下载| 午夜免费福利小电影| 久热这里只有精品视频六| 亚洲人精品午夜射精日韩| 国产精品护士| 欧洲人与动牲交α欧美精品| 在线国产精品中文字幕| 久久久久99精品成人片| 亚洲区日韩精品中文字幕| 亚洲精品日韩在线丰满| 欧美日产国产精品| 天天躁日日躁狠狠躁性色avq| 四虎永久精品在线视频| 中文字幕天天躁日日躁狠狠躁免费| 国产精品亚洲一区二区z| 久久精品无码免费不卡| 武装少女在线观看高清完整版免费| 天堂www在线中文| 久久综合国产一区二区三区| 日本国产精品第一页久久 | 特级做a爰片毛片免费看无码| 久久亚洲美女精品国产精品| 欧美日韩精品一区二区三区高清视频| 欧美激情a∨在线视频播放| 亚洲一区二区av在线|