【问题标题】:gzip JSON payload before POSTPOST 之前的 gzip JSON 有效负载
【发布时间】:2019-07-11 18:00:41
【问题描述】:

我有一个 []byte 类型的 JSON 对象,它是使用 json.Marshal 从结构创建的。我想在将 JSON 发布到我的端点之前对其进行 GZip。以下方法不起作用:

gz := gzip.NewWriter(myJSON)

因为[]byte 没有实现io.Writer

一旦我已经创建了我的 JSON,是否有一些非常简单的方法可以做到这一点?

【问题讨论】:

    标签: json go gzip


    【解决方案1】:

    压缩到缓冲区并发布该缓冲区。

     var buf bytes.Buffer
     gz := gzip.NewWriter(&buf)
     gz.Write(myJSON)
     gz.Close()
    

    因为*bytes.Buffer统计了io.Reader接口,所以创建请求时可以直接使用缓冲区。

     req, err := http.NewRequest("POST", url, &buf)
     if err != nil {
         // handle error
     }
     req.Header.Set("Content-Encoding", "gzip")
     req.Header.Set("Content-Type", "application/json; charset=utf-8")
    

    【讨论】:

    • 谢谢!你在用 'bytesToPost := buf.Bytes()' 做些什么吗?似乎您创建了它,但是当您在 POST 中传递 &buf 时不要使用它。
    • @JimmyD 这行代码旨在说明要发布的字节在哪里,但看起来这并没有帮助。查看更新的答案。
    【解决方案2】:

    最好的选择是将您的 JSON 编组流式传输到您的 gzip 编写器:

    func compressJSON(w io.Writer, i interface{}) error {
        gz := gzip.NewWriter(w)
        if err := json.NewEncoder(gz).Encode(i); err != nil {
            return err
        }
        return gz.Close()
    }
    

    这样做的好处是不会暂时在内存中缓冲你的 json,所以它会更快并且使用更少的 RAM。

    如果您需要将其作为io.Reader,例如用于 HTTP 请求的正文,您可以使用管道进行转换:

    r, w := io.Pipe()
    go func() {
        err := compressJSON(w, someObject)
        w.CloseWithError(err)
    }()
    req, err := http.NewRequest("POST", "http://example.com/", r)
    

    【讨论】:

      猜你喜欢
      • 2021-05-23
      • 1970-01-01
      • 1970-01-01
      • 2014-01-19
      • 2018-07-22
      • 1970-01-01
      • 2015-02-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多