XML HTTP Post in Go

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

XML HTTP Post in Go

问题

我正在尝试创建一个使用XML的POST请求。

我知道我需要使用:

http.Post("myurl", "text/xml", body)

但我无法弄清楚如何设置要发送的实际XML数据。

<request>
    <parameters>
        <email>test@test.com</email>
        <password>test</password>
    </parameters>
</request>

并设置一个头部,使其具有Content-Type: text/xml

英文:

I'm attempting to create a post request that uses xml.

I know I need to use:

http.Post(&quot;myurl&quot;, &quot;text/xml&quot;, body)

But the thing I can't figure out is how to set the actual XML data to be sent.

&lt;request&gt;
    &lt;parameters&gt;
        &lt;email&gt;test@test.com&lt;/email&gt;
        &lt;password&gt;test&lt;/password&gt;
    &lt;/parameters&gt;
&lt;/request&gt;

And setting a header to have Content-Type: text/xml

答案1

得分: 12

不需要自己发起请求或手动设置内容类型,可以通过一个简单的http.Post调用完成所有操作:

package main

import (
	"log"
	"net/http"
	"strings"
)

func main() {
	const myurl = "http://127.0.0.1:8080"
	const xmlbody = `
<request>
    <parameters>
        <email>test@test.com</email>
        <password>test</password>
    </parameters>
</request>`

	resp, err := http.Post(myurl, "text/xml", strings.NewReader(xmlbody))
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()

	// 对resp.Body进行处理
}

无论你使用什么作为bodyType参数,都会放入内容类型头中。
服务器将看到:

POST / HTTP/1.1
Host: 127.0.0.1:8080
User-Agent: Go 1.1 package http
Content-Length: 127
Content-Type: text/xml
Accept-Encoding: gzip


<request>
    <parameters>
        <email>test@test.com</email>
        <password>test</password>
    </parameters>
</request>

(额外的空行是因为我选择在新的一行上开始字符串文字)。

英文:

No need to make your own request or manually set the content type, it can all be done with a single simple http.Post call:

package main

import (
	&quot;log&quot;
	&quot;net/http&quot;
	&quot;strings&quot;
)

func main() {
	const myurl = &quot;http://127.0.0.1:8080&quot;
	const xmlbody = `
&lt;request&gt;
    &lt;parameters&gt;
        &lt;email&gt;test@test.com&lt;/email&gt;
        &lt;password&gt;test&lt;/password&gt;
    &lt;/parameters&gt;
&lt;/request&gt;`

	resp, err := http.Post(myurl, &quot;text/xml&quot;, strings.NewReader(xmlbody))
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()

	// Do something with resp.Body
}

Whatever you use for the bodyType argument goes into the content type header.
The server will see:

POST / HTTP/1.1
Host: 127.0.0.1:8080
User-Agent: Go 1.1 package http
Content-Length: 127
Content-Type: text/xml
Accept-Encoding: gzip


&lt;request&gt;
    &lt;parameters&gt;
        &lt;email&gt;test@test.com&lt;/email&gt;
        &lt;password&gt;test&lt;/password&gt;
    &lt;/parameters&gt;
&lt;/request&gt;

(The extra blank line is because I chose to start the string literal on a new line).

答案2

得分: 8

我也是刚接触Go语言,但我会尽力回答你的问题。

你可以使用http.Clienthttp.NewRequest,然后在发送POST请求之前设置请求头。示例如下:

package main

import (
	"bytes"
	"fmt"
	"net/http"
)

func main() {
	body := "<request> <parameters> <email>test@test.com</email> <password>test</password> </parameters> </request>"

	client := &http.Client{}
	req, err := http.NewRequest("POST", "http://localhost:8080/", bytes.NewBuffer([]byte(body)))
	if err != nil {
		fmt.Println(err)
	}

	req.Header.Add("Content-Type", "application/xml; charset=utf-8")

	resp, err := client.Do(req)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(resp)
}

客户端的响应(虚拟服务器,所以响应肯定不好):

>>> go run xmlpost.go
Post http://localhost:8080/: dial tcp 127.0.0.1:8080: connection refused
<nil>

服务器的响应:

>>> ncat -l 8080
POST / HTTP/1.1
Host: localhost:8080
User-Agent: Go 1.1 package http
Content-Length: 102
Content-Type: application/xml; charset=utf-8
Accept-Encoding: gzip

<request> <parameters> <email>test@test.com</email> <password>test</password> </parameters> </request>

更新:感谢@DaveC指出不必要的io.Reader(...),并为在SO中使用**#**作为注释表示道歉。现在已经修复。

英文:

I am also new to Go, but I'd take a brave trial and try to answer this.

You can use http.Client with http.NewRequest, then set the request header before sending the POST, working sample like this:

package main

import (
	&quot;bytes&quot;
	&quot;fmt&quot;
	&quot;net/http&quot;
)

func main() {
    // or you can use []byte(`...`) and convert to Buffer later on
	body := &quot;&lt;request&gt; &lt;parameters&gt; &lt;email&gt;test@test.com&lt;/email&gt; &lt;password&gt;test&lt;/password&gt; &lt;/parameters&gt; &lt;/request&gt;&quot;

	client := &amp;http.Client{}
    // build a new request, but not doing the POST yet
	req, err := http.NewRequest(&quot;POST&quot;, &quot;http://localhost:8080/&quot;, bytes.NewBuffer([]byte(body)))
	if err != nil {
		fmt.Println(err)
	}
    // you can then set the Header here
    // I think the content-type should be &quot;application/xml&quot; like json...
	req.Header.Add(&quot;Content-Type&quot;, &quot;application/xml; charset=utf-8&quot;)
	// now POST it
    resp, err := client.Do(req)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(resp)
}

Response from Client (dummy server so bad response of course):

&gt;&gt;&gt; go run xmlpost.go
Post http://localhost:8080/: dial tcp 127.0.0.1:8080: connection refused
&lt;nil&gt;

Server Response:

&gt;&gt;&gt; ncat -l 8080
POST / HTTP/1.1
Host: localhost:8080
User-Agent: Go 1.1 package http
Content-Length: 102
Content-Type: application/xml; charset=utf-8
Accept-Encoding: gzip

&lt;request&gt; &lt;parameters&gt; &lt;email&gt;test@test.com&lt;/email&gt; &lt;password&gt;test&lt;/password&gt; &lt;/parameters&gt; &lt;/request&gt;

update:

Thanks for @DaveC pointing out the unnecessary io.Reader(...), and apologized for using # for comment, I'm too used to Python and it came natural when adding comment in SO. Now fixed.

huangapple
  • 本文由 发表于 2015年4月10日 22:28:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/29564032.html
匿名

发表评论

匿名网友

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

确定