英文:
How to do a SOAP call in Go?
问题
鉴于Adwords是Google的产品,而Go也是Google的产品,那么什么时候会有用Go编写的Adwords API版本?
与此问题相关的另一个问题是:目前是否有适用于Go的SOAP库?
英文:
Given that Adwords is a Google thing, and Go is a Google thing, how long until there's a version of the Adwords API written in Go?
Associated with that question, another: are there any SOAP libraries for Go yet?
答案1
得分: 37
我无法回答关于AdWords API的问题,因为我没有看到公司的任何公告,而且很难从外部预测发布的时间。
所以我会回答你的第二个问题。
我不知道Go语言中是否有任何SOAP库(go-lang.cat-v.org似乎没有提到),但是像大多数语言一样,处理简单SOAP消息的方法是使用基本的http和xml库。
两个重要的操作是:
1)通过进行POST查询来获取答案:
resp, err := httpClient.Post(query, "text/xml; charset=utf-8", someXMLasBytes)
2)使用xml.NewDecoder
将其解码为所需的结构:
parser := xml.NewDecoder(bytes.NewBufferString(in))
err = parser.DecodeElement(&envelope, nil)
这是一个完整且有注释的在Go中执行SOAP查询的示例(简化自此处):
package main
import (
"bytes"
"encoding/xml"
"fmt"
"io"
"io/ioutil"
"net/http"
"strings"
)
// SOAP服务器的URL
const MH_SOAP_URL = "http://sp.mountyhall.com/SP_WebService.php"
// 这只是我将用于查询的消息,带有占位符
// 用于我的参数
const SOAP_VUE_QUERY_FORMAT = `<?xml version="1.0" encoding="UTF-8" standalone="no"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tns="urn:SP_WebService" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" ><SOAP-ENV:Body><mns:Vue xmlns:mns="uri:mhSp" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><numero xsi:type="xsd:string">%d</numero><mdp xsi:type="xsd:string">%s</mdp></mns:Vue></SOAP-ENV:Body></SOAP-ENV:Envelope>`
// 在这里定义Go结构,几乎与我们将获取的XML消息的结构相同
// 注意注释(字符串“return>item”)允许具有稍微不同的结构或不同的命名
type SoapItem struct {
Numero int
Nom string
Type string
PositionX int
PositionY int
PositionN int
Monde int
}
type SoapVue struct {
Items []SoapItem "return>item"
}
type SoapFault struct {
Faultstring string
Detail string
}
type SoapBody struct {
Fault SoapFault
ProfilResponse SoapProfil
VueResponse SoapVue
}
type SoapEnvelope struct {
XMLName xml.Name
Body SoapBody
}
// 这是查询SOAP服务器的函数
// 它将整个答案作为Go结构(SoapEnvelope)返回
// 你也可以在第二个返回的参数中返回错误
func GetSoapEnvelope(query string, numero int, mdp string) (envelope *SoapEnvelope) {
soapRequestContent := fmt.Sprintf(query, numero, mdp)
httpClient := new(http.Client)
resp, err := httpClient.Post(MH_SOAP_URL, "text/xml; charset=utf-8", bytes.NewBufferString(soapRequestContent))
if err != nil {
// 处理错误
}
b, e := ioutil.ReadAll(resp.Body) // 可能不高效,因为流不总是纯XML流,我必须修复一些东西(此处未显示)
if e != nil {
// 处理错误
}
in := string(b)
parser := xml.NewDecoder(bytes.NewBufferString(in))
envelope = new(SoapEnvelope) // 这将分配我们将解码XML的结构
err = parser.DecodeElement(&envelope, nil)
if err != nil {
// 处理错误
}
resp.Body.Close()
return
}
英文:
I can' answer about the adwords API as I saw no announcement from the company and predicting the time before a release can hardly be done from outside.
So I'll answer your second question.
I don't know any SOAP library in Go (go-lang.cat-v.org doesn't seem to reference one) but as in most languages, a way to deal with simple SOAP messages is to use the basic http and xml libraries.
The two important operations are
-
to get an answer by doing a POST query :
resp, err := httpClient.Post(query, "text/xml; charset=utf-8", someXMLasBytes)
-
to decode it using a
xml.NewDecoder
into the desired structure :parser := xml.NewDecoder(bytes.NewBufferString(in))
err = parser.DecodeElement(&envelope, nil)
Here's a complete and commented example of a SOAP query done in Go (simplified from this) :
package main
import (
"bytes"
"encoding/xml"
"fmt"
"io"
"io/ioutil"
"net/http"
"strings"
)
// The URL of the SOAP server
const MH_SOAP_URL = "http://sp.mountyhall.com/SP_WebService.php"
// this is just the message I'll send for interrogation, with placeholders
// for my parameters
const SOAP_VUE_QUERY_FORMAT = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?><SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:tns=\"urn:SP_WebService\" xmlns:soap=\"http://schemas.xmlsoap.org/wsdl/soap/\" xmlns:wsdl=\"http://schemas.xmlsoap.org/wsdl/\" xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\" ><SOAP-ENV:Body><mns:Vue xmlns:mns=\"uri:mhSp\" SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><numero xsi:type=\"xsd:string\">%d</numero><mdp xsi:type=\"xsd:string\">%s</mdp></mns:Vue></SOAP-ENV:Body></SOAP-ENV:Envelope>"
// Here I define Go structures, almost identical to the structure of the
// XML message we'll fetch
// Note that annotations (the string "return>item") allow to have a slightly
// different structure or different namings
type SoapItem struct {
Numero int
Nom string
Type string
PositionX int
PositionY int
PositionN int
Monde int
}
type SoapVue struct {
Items []SoapItem "return>item"
}
type SoapFault struct {
Faultstring string
Detail string
}
type SoapBody struct {
Fault SoapFault
ProfilResponse SoapProfil
VueResponse SoapVue
}
type SoapEnvelope struct {
XMLName xml.Name
Body SoapBody
}
// Here is the function querying the SOAP server
// It returns the whole answer as a Go structure (a SoapEnvelope)
// You could also return an error in a second returned parameter
func GetSoapEnvelope(query string, numero int, mdp string) (envelope *SoapEnvelope) {
soapRequestContent := fmt.Sprintf(query, numero, mdp)
httpClient := new(http.Client)
resp, err := httpClient.Post(MH_SOAP_URL, "text/xml; charset=utf-8", bytes.NewBufferString(soapRequestContent))
if err != nil {
// handle error
}
b, e := ioutil.ReadAll(resp.Body) // probably not efficient, done because the stream isn't always a pure XML stream and I have to fix things (not shown here)
if e != nil {
// handle error
}
in := string(b)
parser := xml.NewDecoder(bytes.NewBufferString(in))
envelope = new(SoapEnvelope) // this allocates the structure in which we'll decode the XML
err = parser.DecodeElement(&envelope, nil)
if err != nil {
// handle error
}
resp.Body.Close()
return
}
答案2
得分: 1
Google APIs for Go是一个正在进行中的工作。
英文:
The Google APIs for Go is a work in progress.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论