Golang中如何读取HTTP客户端的400响应体

Golang中如何读取HTTP客户端的400响应体 请问如何访问这个HTTP响应的最后一个缓冲区值:

image

我尝试了 errBody, errReadBody := ioutil.ReadAll(resp.Body),但它是空的。

7 回复

没有HTTP请求信息。如果状态码为400,则请求对象无效。

更多关于Golang中如何读取HTTP客户端的400响应体的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


从你的截图中我看不出问题所在。你是否有自己编写的、未能按预期运行的示例代码可以分享?

我也尝试了:

dump, err := httputil.DumpResponse(resp, true)
		fmt.Printf("%q", dump)

我请求我的服务器返回一个HTTP 400状态码,并在响应体中包含一个错误码。

我可以在Goland IDE调试器中看到这个错误,但我想处理它。我需要能够将其作为字符串读取以便进行正则表达式匹配……但我无法使用Go的http Response来获取其内容。

fstn:

我尝试了 errBody, errReadBody := ioutil.ReadAll(resp.Body),但它是空的

到底什么为空?

当你说 errBody 为空时,你是怎么检查的?同时,errReadBody 的值是什么?

能否请你展示更多关于你如何发起请求以及检查其响应的代码?

在断点处调试时,我可以看到:

HTTP/1.1 400 
Content-Type: application/json
Transfer-Encoding: chunked
Date: Thu, 16 Dec 2021 21:52:32 GMT
Connection: close

38d
{"timestamp":1639691552111,"status":400,"error":"Bad Request","exception":"org.springframework.http.converter.HttpMessageNotReadableException","message":"JSON parse error: Unrecognized field \"geoCriteria\" (class google.ads.controllers.PostCampaignController$Campaign), not marked as ignorable; nested exception is com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field \"geoCriteria\" (class google.ads.controllers.PostCampaignController$Campaign), not marked as ignorable (8 known properties: \"status\", \"urls\", \"budget\", \"biddingStrategyType\", \"getGeoCriteria\", \"end\", \"start\", \"languagesCriteria\"])\n at [Source: (PushbackInputStream); line: 1, column: 64] (through reference chain: google.ads.controllers.PostCampaignController$PostCampaignBody[\"campaign\"]->google.ads.controllers.PostCampaignController$Campaign[\"geoCriteria\"])","path":"/post/campaign"}

在Golang中读取HTTP客户端的400响应体,需要确保在读取响应体之前没有进行过其他读取操作。根据你的代码片段,问题可能在于响应体已经被部分读取或关闭。以下是一个完整的示例:

package main

import (
    "fmt"
    "io"
    "net/http"
)

func main() {
    // 发送一个会返回400错误的请求
    resp, err := http.Get("http://httpbin.org/status/400")
    if err != nil {
        fmt.Printf("请求错误: %v\n", err)
        return
    }
    defer resp.Body.Close()

    // 读取整个响应体
    body, err := io.ReadAll(resp.Body)
    if err != nil {
        fmt.Printf("读取响应体错误: %v\n", err)
        return
    }

    fmt.Printf("状态码: %d\n", resp.StatusCode)
    fmt.Printf("响应体: %s\n", string(body))
}

如果响应体为空,可能是因为服务器没有返回响应体,或者响应体已经被读取过。你可以通过以下方式检查:

// 检查Content-Length头
if resp.ContentLength > 0 {
    body, err := io.ReadAll(resp.Body)
    if err != nil {
        fmt.Printf("读取错误: %v\n", err)
        return
    }
    fmt.Printf("响应体: %s\n", string(body))
} else {
    fmt.Println("响应体为空")
}

对于你的具体问题,访问"最后一个缓冲区值"可能指的是读取响应体的最后一部分。可以使用io.ReadAll读取整个响应体后处理:

body, err := io.ReadAll(resp.Body)
if err != nil {
    // 处理错误
}
if len(body) > 0 {
    lastByte := body[len(body)-1]
    fmt.Printf("最后一个字节: %v\n", lastByte)
}

注意:ioutil.ReadAll在Go 1.16后已弃用,建议使用io.ReadAll

回到顶部