当解码失败时,获取原始的 XML。

huangapple go评论93阅读模式
英文:

Get original xml when failing to decode

问题

我有一些类似这样的代码:

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(&qResult)
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,一旦读取,就无法再次读取(或者我错了吗?)。有没有办法可以获取它,或者我必须将初始响应存储在某个地方并传递副本?

英文:

(go newbie here)
I have some code like this:

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
}

And then called like this:

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)
		}

I want to log the original xml that was failed to be processed, but since this is a ReadCloser and once read, it cannot be read again (or am I wrong?). Is there a way I can get this, or do I have to store the initial response somewhere and pass copies around?

答案1

得分: 4

  1. 使用io/ioutilReadAll函数读取字节流

    defer body.Close()

    data, err := ioutil.ReadAll(body)

  2. 然后进行解析

    err = xml.Unmarshal(data, &qResult)

你可以记录下data以检查原始的 XML 数据。

英文:
  1. Read bytes with io/ioutil ReadAll

    defer body.Close()

    data, err := ioutil.ReadAll(body)

  2. Then unmarshal

    err = xml.Unmarshal(data, &qResult)

You can log data for checking original xml.

答案2

得分: 0

对于HTTP响应,您可以使用httputil包的DumpResponse函数:

以下是链接中的示例代码:

package main

import (
	"fmt"
	"log"
	"net/http"
	"net/http/httptest"
	"net/http/httputil"
)

func main() {
	const body = "Go是一种以系统编程为目标的通用编程语言。"
	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)
}
英文:

For http responses you can use the httputil package's DumpResponse:

Example from the link:

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)

}

huangapple
  • 本文由 发表于 2016年9月9日 20:30:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/39411656.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定