用 Go 解码 gZip json
Decoding gZip json with Go
作为一个 Go 新手,我很难找出问题所在,但希望给你一些事实会有所帮助。
我正在玩一个 API,returns 它的 Content-Encoding
作为 gzip。我写了以下内容来编码我的响应结构:
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)
为简洁起见,我删除了错误处理,但有趣的是,如果我取消注释打印到标准输出,我会得到预期的结果。但是,解码并没有给我我所期望的。任何指针?结构是否必须准确映射到响应?
正如@icza 在评论中提到的,不需要解码,因为 gzip reader 在您使用它阅读时会自动解码。也许试试:
ubs := make([]byte, len) // check Content-Length header to set len
n, err := reader.Read(ubs)
err := json.Unmarshal(ubs, &response)
DisableCompression, if true, prevents the Transport from requesting
compression with an "Accept-Encoding: gzip" request header when the
Request contains no existing Accept-Encoding value. If the Transport
requests gzip on its own and gets a gzipped response, it's
transparently decoded in the Response.Body. However, if the user
explicitly requested gzip it is not automatically uncompressed.
建议的解决方案:
type gzreadCloser struct {
*gzip.Reader
io.Closer
}
func (gz gzreadCloser) Close() error {
return gz.Closer.Close()
}
// 然后在你的 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 {
}
根据您的代码改编的解决方案:https://play.golang.org/p/Vt07y_xgak
作为一个 Go 新手,我很难找出问题所在,但希望给你一些事实会有所帮助。
我正在玩一个 API,returns 它的 Content-Encoding
作为 gzip。我写了以下内容来编码我的响应结构:
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)
为简洁起见,我删除了错误处理,但有趣的是,如果我取消注释打印到标准输出,我会得到预期的结果。但是,解码并没有给我我所期望的。任何指针?结构是否必须准确映射到响应?
正如@icza 在评论中提到的,不需要解码,因为 gzip reader 在您使用它阅读时会自动解码。也许试试:
ubs := make([]byte, len) // check Content-Length header to set len
n, err := reader.Read(ubs)
err := json.Unmarshal(ubs, &response)
DisableCompression, if true, prevents the Transport from requesting compression with an "Accept-Encoding: gzip" request header when the Request contains no existing Accept-Encoding value. If the Transport requests gzip on its own and gets a gzipped response, it's transparently decoded in the Response.Body. However, if the user explicitly requested gzip it is not automatically uncompressed.
建议的解决方案:
type gzreadCloser struct {
*gzip.Reader
io.Closer
}
func (gz gzreadCloser) Close() error {
return gz.Closer.Close()
}
// 然后在你的 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 {
}
根据您的代码改编的解决方案:https://play.golang.org/p/Vt07y_xgak