英文:
Reading content from http.Get in Golang
问题
我在Go语言中读取GET
请求的XML时遇到了困难。我刚开始学习Go,并没有找到关于这个主题的任何资源。我尝试了以下方法:
response, err := http.Get(url)
if err != nil {
log.Fatal(err)
} else {
defer response.Body.Close()
xml, _ := ioutil.ReadAll(response.Body)
if err != nil {
log.Fatal(err)
}
}
_, err := io.Copy(os.Stdout, response.Body)
可以工作,但我想将XML存储起来以供进一步处理。非常感谢任何帮助。
英文:
I'm having a tough time reading XML from a GET
request in Go. I just started to learn Go and haven't found any resources on this topic. What I tried:
response, err := http.Get(url)
if err != nil {
log.Fatal(err)
} else {
defer response.Body.Close()
xml, _ := ioutil.ReadAll(response.Body)
if err != nil {
log.Fatal(err)
}
}
_, err := io.Copy(os.Stdout, response.Body)
works but I'd like to store the XML for further processing.
Any help is greatly appreciated.
答案1
得分: 22
你尝试的大部分都很好,有几点可以改进:
http.Get()
返回一个 http.Response
和一个可选的错误。如果没有错误,那只意味着 HTTP GET 操作成功,但服务器可能会返回一个错误文档。所以你仍然需要检查响应的 HTTP 状态码。
另外 io.ReadAll()
也会返回一个错误(除了读取的数据),不要忘记检查它。
让我们把它封装成一个函数:
func getXML(url string) (string, error) {
resp, err := http.Get(url)
if err != nil {
return "", fmt.Errorf("GET error: %v", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return "", fmt.Errorf("Status error: %v", resp.StatusCode)
}
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", fmt.Errorf("Read body: %v", err)
}
return string(data), nil
}
测试/使用上述函数:
if xmlStr, err := getXML("http://somehost.com/some.xml"); err != nil {
log.Printf("Failed to get XML: %v", err)
} else {
log.Println("Received XML:")
log.Println(xmlStr)
}
还要注意,获取其他响应的内容也是一样的,所以不值得对 string
进行 "编码" 转换和返回类型。这个函数更通用:
func getContent(url string) ([]byte, error) {
resp, err := http.Get(url)
if err != nil {
return nil, fmt.Errorf("GET error: %v", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("Status error: %v", resp.StatusCode)
}
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("Read body: %v", err)
}
return data, nil
}
使用它来获取一个 XML 文档:
if data, err := getContent("http://somehost.com/some.xml"); err != nil {
log.Printf("Failed to get XML: %v", err)
} else {
log.Println("Received XML:")
log.Println(string(data))
}
英文:
What you've tried is mostly good. Few things to improve it:
http.Get()
returns an http.Response
and an optional error. If there is no error, that only means that the HTTP GET operation succeeded, but the server might have responded with an error document. So you still have to check the response HTTP status code.
Also io.ReadAll()
also returns an error (besides the read data), don't forget to check that too.
Let's wrap it in a function:
func getXML(url string) (string, error) {
resp, err := http.Get(url)
if err != nil {
return "", fmt.Errorf("GET error: %v", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return "", fmt.Errorf("Status error: %v", resp.StatusCode)
}
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", fmt.Errorf("Read body: %v", err)
}
return string(data), nil
}
Testing / using the above function:
if xmlStr, err := getXML("http://somehost.com/some.xml"); err != nil {
log.Printf("Failed to get XML: %v", err)
} else {
log.Println("Received XML:")
log.Println(xmlStr)
}
Also note that it would be the same to get the content of any other responses, so it's worth not "encoding" the string
conversion and return type. This one is more general:
func getContent(url string) ([]byte, error) {
resp, err := http.Get(url)
if err != nil {
return nil, fmt.Errorf("GET error: %v", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("Status error: %v", resp.StatusCode)
}
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("Read body: %v", err)
}
return data, nil
}
Using this to get an XML doc:
if data, err := getContent("http://somehost.com/some.xml"); err != nil {
log.Printf("Failed to get XML: %v", err)
} else {
log.Println("Received XML:")
log.Println(string(data))
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论