【问题标题】:Get original xml when failing to decode解码失败时获取原始xml
【发布时间】:2017-01-17 14:37:33
【问题描述】:

(这里是新手) 我有一些这样的代码:

func (c *clientImpl) queryHost(qtype string, page int) (io.ReadCloser, error) {
    queryURI := c.URL + "/api/query"
    req, _ := http.NewRequest(http.MethodGet, queryURI, nil)
    req.Header.Add(authHeaderName, authToken)
    req.Header.Add("Accept", accept)

    q := req.URL.Query()
    q.Add("type", qtype)
    q.Add("pageSize", pageSize)
    q.Add("page", strconv.Itoa(page))
    req.URL.RawQuery = q.Encode()
    resp, err := c.client.Do(req) //*http.Client
    if err != nil {
        return nil, utils.NestedError("Error in querying Host", err)
    }

    return resp.Body, nil
}

然后这样调用:

body, err := c.queryHost(myQType, i)
        if err != nil {
            log.Printf("Error while trying to get page %v - %v \n", i, err)
            return err
        }
        defer body.Close()

        var qResult myQueryResult
        err = xml.NewDecoder(body).Decode(&myQueryResult)
        if err != nil {
            log.Printf("Error while decoding page %v - %v \n", i, err)
            return utils.NestedError("Error in decoding response body xml", err)
        }

我想记录未能处理的原始 xml,但由于这是一个 ReadCloser,并且一旦读取,就无法再次读取(或者我错了吗?)。有什么办法可以得到这个,还是我必须将初始响应存储在某个地方并传递副本?

【问题讨论】:

    标签: xml go


    【解决方案1】:
    1. 使用io/ioutilReadAll 读取字节

      defer body.Close()

      data, err := ioutil.ReadAll(body)

    2. 然后解组

      err = xml.Unmarshal(data, &qResult)

    您可以记录数据以检查原始xml。

    【讨论】:

    【解决方案2】:

    对于 http 响应,您可以使用 httputil 包的 DumpResponse

    链接示例:

    package main
    
    import (
        "fmt"
        "log"
        "net/http"
        "net/http/httptest"
        "net/http/httputil"
    )
    
    func main() {
        const body = "Go is a general-purpose language designed with systems programming in mind."
        ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            w.Header().Set("Date", "Wed, 19 Jul 1972 19:00:00 GMT")
            fmt.Fprintln(w, body)
        }))
        defer ts.Close()
    
        resp, err := http.Get(ts.URL)
        if err != nil {
            log.Fatal(err)
        }
        defer resp.Body.Close()
    
        dump, err := httputil.DumpResponse(resp, true)
        if err != nil {
            log.Fatal(err)
        }
    
        fmt.Printf("%q", dump)
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-02-26
      • 1970-01-01
      • 2019-06-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多