从Golang的http.Get中读取内容

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

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

huangapple
  • 本文由 发表于 2017年3月10日 19:48:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/42717716.html
匿名

发表评论

匿名网友

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

确定