从RESTful API的POST类型方法中获取响应。

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

Get response from POST type method from restful API

问题

如何从POST方法中获取JSON响应?目前我只能获取到状态码401 Unauthorized和状态码401。

func postUrl(url string, byt []byte) (*http.Response, error) {
    tr := &http.Transport{
        DisableCompression: true,
    }
    client := &http.Client{Transport: tr, Timeout: 10 * time.Second}
    req, err := http.NewRequest("POST", url, bytes.NewBuffer(byt))
    req.Header.Set("X-Custom-Header", "myvalue")
    req.Header.Set("Content-Type", "application/json")
    req.Header.Add("Authorization", "Basic "+basicAuth("username", "password"))
    resp, err := client.Do(req)
    return resp, err
}

上述代码产生的输出为:

{
  "errorMessages": [
    "You do not have the permission to see the specified issue.",
    "Login Required"
  ],
  "errors": {}
}
英文:

How can I fetch the json response from the POST method? Currently I'm only able to fetch Status - 401 Unauthorized and StatusCode - 401

func postUrl(url string, byt []byte) (*http.Response, error) {
    tr := &http.Transport{
	    DisableCompression: true,
    }
    client := &http.Client{Transport: tr, Timeout: 10 * time.Second}
    req, err := http.NewRequest("POST", url, bytes.NewBuffer(byt))
    req.Header.Set("X-Custom-Header", "myvalue")
    req.Header.Set("Content-Type", "application/json")
    req.Header.Add("Authorization", "Basic "+basicAuth("username", "password"))
    resp, err := client.Do(req)
    return resp, err
  }

Above code produces the output:

{
  "errorMessages": [
    "You do not have the permission to see the specified issue.",
    "Login Required"
  ],
    "errors": {}
}

答案1

得分: 1

读取响应的方式(如果有响应)无论你得到什么状态都是相同的。

defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
英文:

The way to read the response (if there is one) is the same regardless of what status you get.

defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)

答案2

得分: 0

正如Frank所说,无论响应中的状态码如何,您都可以简单地读取其主体以使用其中的内容。

特别是对于JSON消息的情况,根据您是否事先了解JSON消息的结构(或者希望您的代码依赖于它),您有两个选项。

如果您知道结构并且愿意硬编码它(还可以获得一些类型安全性和更好的客户端代码),您可以使用以下方式:

type ErrorResponse struct {
    Messages []string `json:"errorMessages"`
}

然后,当您检测到错误状态码时,将响应主体解组为该结构:

if resp.StatusCode % 100 != 2 {
    var error ErrorResponse
    err := json.Unmarshal(resp.Body, &error)
    // 检查 err != nil ...
    // 使用 error.ErrorMessages 进行您想要的操作
}

或者,如果您不想在某种程度上依赖于JSON结构,您可以尝试将其解组为 map[string]interface{},并尝试以您认为可以的通用方式使用它(通常不是非常有用)。

英文:

As Frank said, regardless of the status code in the response you can simply read its body to use whatever content it has.

Particularly for the case of a JSON message, you have two options depending on whether you know the JSON message structure in advance (or want your code to depend on it).

If you know the structure and are ok with hard-coding it (plus you gain some type safety and better client code) you can have:

type ErrorResponse struct {
    Messages []string `json:"errorMessages"`
}

And then when you detect an error status code unmarshal the response body as that struct:

if resp.StatusCode % 100 != 2 {
    var error ErrorResponse
    err := json.Unmarshall(resp.Body, &error)
    // check err != nil ...
    // user error.ErrorMessages for whatever you want 
}

Alternatively if you don't want to depend on the JSON structure (to some degree) you can try to unmarshall it to a map[string]interface{} and try to use that in the generic way you think you can (generally not very useful).

答案3

得分: 0

这个问题与HTTP响应和HTTP方法无关。使用JSON解码器解码JSON字符串(在这种情况下是HTTP响应体)。

简单示例

(与您的代码片段不直接相关)

type Transition struct {
    Transition map[string]int
}

func main() {
    resp, err := postUrl(url, byt)
    if err != nil {
        log.Fatal(err)
    }

    var trans Transition
    decoder := json.NewDecoder(resp.Body)

    if err := decoder.Decode(&trans); err != nil {
        log.Fatal(err)
    }

    fmt.Printf("%+v\n", trans)
}
英文:

This question is not related to http responses and http methods. Decode json string (wich is http response body in that case) with json decoder.

Simple example

(not directly related to your code snippet)

type Transition struct {
    Transition map[string]int
}

func main() {
    resp, err := postUrl(url, byt)
    if err != nil {
        log.Fatal(err)
    }

    var trans Transition
    decoder := json.NewDecoder(resp.Body)

    if err := decoder.Decode(&trans); err != nil {
        log.Fatal(err)
    }

    fmt.Printf("%+v\n", trans)
}

huangapple
  • 本文由 发表于 2016年12月29日 21:38:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/41380899.html
匿名

发表评论

匿名网友

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

确定