【问题标题】:How to do a SOAP call in Go? [closed]如何在 Go 中进行 SOAP 调用? [关闭]
【发布时间】:2012-08-28 16:36:48
【问题描述】:

鉴于 Adwords 是 Google 的东西,而 Go 是 Google 的东西,那么多久之后会有一个用 Go 编写的 Adwords API 版本?

与这个问题相关的另一个问题是:还有 Go 的 SOAP 库吗?

【问题讨论】:

  • 我可以通过简单地使用 http 和 xml 包轻松地进行 SOAP 调用。
  • @dystroy:你说得很好。但是,我刚刚开始使用 Go,所以这还不是一个解决方案。
  • 您是否希望我详细说明(在回答中)如何在 Go 中轻松进行 SOAP 调用?
  • @dystroy:我非常喜欢。提前致谢。感谢会跟进。
  • 参见this answer 在 Go 中进行 SOAP 调用。

标签: soap go google-ads-api


【解决方案1】:

我无法回答有关 adwords API 的问题,因为我没有看到该公司的任何公告,并且很难从外部预测发布前的时间。

所以我会回答你的第二个问题。

我不知道 Go 中的任何 SOAP 库(go-lang.cat-v.org 似乎没有引用一个),但在大多数语言中,处理简单 SOAP 消息的一种方法是使用基本的 http 和 @987654323 @图书馆。

两个重要的操作是

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 (simplified from this) 完成的 SOAP 查询的完整示例:

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
}

【讨论】:

  • 在上面的例子中,你使用的是硬编码的 xml,有没有我们可以生成soap xml的包
  • 我认为该模板生成的 XML 比硬编码的 xml 更多。您可以尝试使用 encoding/xml 生成 XML,但您会很快发现每个服务器都需要不同的东西,因此根据我的经验,至少您最好手动摆弄 XML,直到您让服务器响应如何你想要然后只是硬编码它,而不是让一个库为你生成它并且必须调整库直到它一致地生成你想要的东西。
【解决方案2】:

Google APIs for Go 正在进行中。

【讨论】:

  • 我还没有看到任何关于 AdWords 的提及。您确定当前的 Google API 涵盖了这一点吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多