用 Go 解码 gZip json

Sio*_*ion 5 json gzip go

作为 Go 新手,我很难确定问题区域,但希望为您提供一些事实会有所帮助。

我正在使用一个Content-Encoding以 gzip形式返回的 API 。我编写了以下内容来编码我的响应结构:

reader, err = gzip.NewReader(resp.Body)
defer reader.Close()

// print to standard out
//_, err = io.Copy(os.Stdout, reader)
//if err != nil {
//  log.Fatal(err)
//}

// Decode the response into our tescoResponse struct
var response TescoResponse
err := json.NewDecoder(reader).Decode(&response)
Run Code Online (Sandbox Code Playgroud)

为简洁起见,我删除了错误处理,但有趣的是,如果我取消对 stdout 打印的注释,我会得到预期的结果。但是,解码并没有给我我所期望的。任何指针?是不是结构必须完全映射到响应?

这是完整的示例:https : //play.golang.org/p/4eCuXxXm3T

Eze*_*eno 6

从文档中

DisableCompression,如果为真,当请求不包含现有的接受编码值时,阻止传输请求带有“接受编码:gzip”请求标头的压缩。如果传输自行请求 gzip 并获得 gzip 响应,则它会在 Response.Body 中透明解码。但是,如果用户明确请求 gzip,它不会自动解压缩。

建议的解决方案:

type gzreadCloser struct {
    *gzip.Reader
    io.Closer
}

func (gz gzreadCloser) Close() error {
    return gz.Closer.Close()
}
Run Code Online (Sandbox Code Playgroud)

// 然后在你的 http 调用中 ....

    if resp.Header.Get("Content-Encoding") == "gzip" {
        resp.Header.Del("Content-Length")
        zr, err := gzip.NewReader(resp.Body)
        if err != nil {
            return nil, err
        }
        resp.Body = gzreadCloser{zr, resp.Body}
    }

// then you will be able to decode the json transparently

if err := json.NewDecoder(resp.Body).Decode(&response); err != nil {

}
Run Code Online (Sandbox Code Playgroud)

根据您的代码改编的解决方案:https : //play.golang.org/p/Vt07y_xgak