将HTTP请求中的字符串转换为Go中的数据结构

huangapple go评论78阅读模式
英文:

Converting string from HTTP request to data struct in Go

问题

我有一个HTTP Post方法,成功地将数据发布到外部第三方API并返回响应。

然后,我需要从这个响应中返回的数据发布到我的数据库。

响应包含一些数据,但我只需要其中的'access_token'和'refresh_token'。

因此,我尝试将响应从字符串转换为我创建的新数据结构中的单个组件,然后传递给我的数据库。

然而,尽管成功写入到我的浏览器,但数据显示为空。显然,我做错了一些基本的事情,但不确定是什么。。

这是我的代码:

type data struct {
	Access_token  string `json:"access_token"`
	Refresh_token string `json:"refresh_token"`
}

func Fetch(w http.ResponseWriter, r *http.Request) {

	client := &http.Client{}

	q := url.Values{}

	q.Add("grant_type", "authorization_code")
	q.Add("client_id", os.Getenv("ID"))
	q.Add("client_secret", os.Getenv("SECRET"))
	q.Add("redirect_uri", "https://callback-url.com")
	q.Add("query", r.URL.Query().Get("query"))

	req, err := http.NewRequest("POST", "https://auth.truelayer-sandbox.com/connect/token", strings.NewReader(q.Encode()))

	if err != nil {
		log.Print(err)
		fmt.Println("Error was not equal to nil at first stage.")
		os.Exit(1)
	}

	req.Header.Add("Content-Type", "application/x-www-form-urlencoded")

	resp, err := client.Do(req)
	if err != nil {
		fmt.Println("Error sending request to server")
		os.Exit(1)
	}

	respBody, _ := ioutil.ReadAll(resp.Body)

	d := data{}

	err = json.NewDecoder(resp.Body).Decode(&d)
	if err != nil {
		fmt.Println(err)
	}

	fmt.Println(d.Access_token)
	fmt.Println(d.Refresh_token)

	w.WriteHeader(resp.StatusCode)
	w.Write(respBody)

}
英文:

I've got an HTTP Post method, which successfully posts data to an external third party API and returns a response.

I then need data returned from this response to post to my database.

The response contains a few piece of data, but I only need the 'access_token' and 'refresh_token' from it.

As a result, what I'm attempting to do is convert the response from a string into individual components in a new data struct I've created - to then pass to my database.

However, the data is showing as blank, despite it successfully being written to my browser. I'm obviously doing something fundamentally wrong, but not sure what..

Here's my code:

type data struct {
	Access_token  string `json:"access_token"`
	Refresh_token string `json:"refresh_token"`
}

func Fetch(w http.ResponseWriter, r *http.Request) {

	client := &http.Client{}

	q := url.Values{}

	q.Add("grant_type", "authorization_code")
	q.Add("client_id", os.Getenv("ID"))
	q.Add("client_secret", os.Getenv("SECRET"))
	q.Add("redirect_uri", "https://callback-url.com")
	q.Add("query", r.URL.Query().Get("query"))

	req, err := http.NewRequest("POST", "https://auth.truelayer-sandbox.com/connect/token", strings.NewReader(q.Encode()))

	if err != nil {
		log.Print(err)
		fmt.Println("Error was not equal to nil at first stage.")
		os.Exit(1)
	}

	req.Header.Add("Content-Type", "application/x-www-form-urlencoded")

	resp, err := client.Do(req)
	if err != nil {
		fmt.Println("Error sending request to server")
		os.Exit(1)
	}

	respBody, _ := ioutil.ReadAll(resp.Body)

	d := data{}

	err = json.NewDecoder(resp.Body).Decode(&d)
	if err != nil {
		fmt.Println(err)
	}

	fmt.Println(d.Access_token)
	fmt.Println(d.Refresh_token)

	w.WriteHeader(resp.StatusCode)
	w.Write(respBody)

}

答案1

得分: 6

使用ioutil.ReadAll,你已经读取了响应体。第二次将其传递给NewDecoder(resp.Body)时,流已经被消耗掉了。

你可以使用json.Unmarshal(respBody, &d)来代替。

还有一个建议,不要忽略ioutil.ReadAll的错误。

英文:

With ioutil.ReadAll you read the body, already. The second time you pass to NewDecoder(resp.Body) the stream was consumed.

You can use instead json.Unmarshal(respBody, &d).

One more advice, don't ignore the error on ioutil.ReadAll

huangapple
  • 本文由 发表于 2021年10月5日 19:01:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/69449254.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定