英文:
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
-
使用
io/ioutil
的ReadAll
函数读取字节流defer body.Close()
data, err := ioutil.ReadAll(body)
-
然后进行解析
err = xml.Unmarshal(data, &qResult)
你可以记录下data以检查原始的 XML 数据。
英文:
-
Read bytes with
io/ioutil
ReadAlldefer body.Close()
data, err := ioutil.ReadAll(body)
-
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)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论