go的http请求和传参的坑

2019-04-15  本文已影响0人  编程_书恨少

0.最下方有完整代码

1.需求

最近接了新的任务,要用go把其他部门的python的接口接过来,那么开始吧

2.目前持有的条件

a.go刚开始看
b.接口没有文档,只有python的代码,python咱也不会(并不骄傲)
那么开始吧

3.开始实现

a.搜索go的http请求是怎么进行的

然后发现可以直接使用http的api进行post请求,如下方法

    // 进行请求
    reqest, err := http.PostForm(my_url, url.Values{"Text": {"你好"}})
    // 设置请求头
    reqest.Header.Set("Content-Type", "application/json")
    reqest.Header.Set("Ocp-Apim-Subscription-Key", key)

但是这样请求的话header是没有地方设置的,因为在第一行就已经开始请求了,但是请求之后才返回request,再设置header为时已晚。这里不知道是不是我刚开始写go,还不知道具体的使用方法,还是说这样请求的话就是无法设置header。
结论:所以这种方式pass

b.还有一种写法是用client

    client := &http.Client{
        Timeout: time.Second * 2,
    }

    req, err := http.NewRequest("POST", uri, r)
    if err != nil {
        fmt.Printf("Error creating request: %v\n", err)
        return
    }
    // 设置header
    req.Header.Add("Content-Type", "application/json")
    req.Header.Add("Content-Length", strconv.FormatInt(req.ContentLength, 10))
    req.Header.Add("Ocp-Apim-Subscription-Key", subscriptionKey)
    // 在这里开始进行请求
    resp, err := client.Do(req)

这种方法可以在设置好头部之后再进行请求,所以我们使用这种方法。

c.开始传参

关于传参的方法,网上搜出来的五花八门,就是不能用,也是非常的服气了,看到的帖子都是互相抄的,也是很无语。
我这里请求的服务器地址有微软的和谷歌的,参数要求都是json格式,但是很神奇的,参数结构却不一样,这个还是在我反复试验之后,蒙对的,没有文档真的举步维艰

const params = "&to=zh-Hans&from=en"

    const uri = uriBase + uriPath + params

    fmt.Println(uri)

    const text = "Hello, nice to meet you!"

    r := strings.NewReader("[{\"Text\" : \"" + text + "\"}]")

    client := &http.Client{
        Timeout: time.Second * 2,
    }

    req, err := http.NewRequest("POST", uri, r)
    if err != nil {
        fmt.Printf("Error creating request: %v\n", err)
        return
    }

这个是访问微软接口时的传参方式,strings.NewReader里面就是参数的body,但是两边竟然是数组的格式,也是神奇了,所以就一直访问通,报的错误各种各样,有说没有权限访问的,有说key传的不对的,有说json的不可用的,最后一个提示是对的,但是我并不知道json的格式还需要两边加[],真的没见过。
后来这么写之后终于算是通了

d.换接口传参

微软的接口通了之后,再接谷歌的接口应该就是换个参数的事,想着应该没什么坑了,可是不然。
谷歌的格式是这样的

    r := strings.NewReader("{\"q\" : \"" + text + "\", \"source\" : \"" + source + "\", \"target\" : \"" + target + "\", \"model\" : \"" + model + "\"}")

这种是我们传统认为的json格式。

至此,两个接口就都通了。

4.完整代码

就以谷歌的为例,参数还多一些

package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "net/http"
    "strings"
    "time"
)

func main9() {
    // Replace the subscriptionKey string value with your valid subscription key
    const subscriptionKey = "keykeykeykeykey"

    const uriBase = "https://xxxxx.googleapis.com"
    const uriPath = "/aaaa/bbbb/v2"

    // Translate to German and Italian
    const params = "?key=" + subscriptionKey

    const uri = uriBase + uriPath + params

    fmt.Println(uri)

    const text = "Hello, i am google service!"

    source := "en"
    target := "zh-Hans"
    model := "nmt"
    r := strings.NewReader("{\"q\" : \"" + text + "\", \"source\" : \"" + source + "\", \"target\" : \"" + target + "\", \"model\" : \"" + model + "\"}")

    client := &http.Client{
        Timeout: time.Second * 2,
    }

    req, err := http.NewRequest("POST", uri, r)
    if err != nil {
        fmt.Printf("Error creating request: %v\n", err)
        return
    }

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

    resp, err := client.Do(req)
    if err != nil {
        fmt.Printf("Error on request: %v\n", err)
        return
    }
    defer resp.Body.Close()

    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        fmt.Printf("Error reading response body: %v\n", err)
        return
    }

    var f interface{}
    json.Unmarshal(body, &f)

    jsonFormatted, err := json.MarshalIndent(f, "", "  ")
    if err != nil {
        fmt.Printf("Error producing JSON: %v\n", err)
        return
    }
    fmt.Println(string(jsonFormatted))
}

上一篇 下一篇

猜你喜欢

热点阅读