加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

用Golang调用SOAP

发布时间:2020-12-16 19:04:43 所属栏目:大数据 来源:网络整理
导读:我是golang的新手,并尝试用 gowsdl拨打肥皂. 我生成了wsdl代码并将其作为包安装.但是我很难理解从中调用方法的语法. 当我检查包装时,这就是我想要的肥皂体: type AccountUser struct { XMLName xml.Name `xml:"http://exacttarget.com/wsdl/partnerAPI Acco
我是golang的新手,并尝试用 gowsdl拨打肥皂.

我生成了wsdl代码并将其作为包安装.但是我很难理解从中调用方法的语法.

当我检查包装时,这就是我想要的肥皂体:

type AccountUser struct {
    XMLName xml.Name `xml:"http://exacttarget.com/wsdl/partnerAPI AccountUser"`

    *APIObject

    AccountUserID             int32         `xml:"AccountUserID,omitempty"`
    UserID                    string        `xml:"UserID,omitempty"`
    Password                  string        `xml:"Password,omitempty"`
    Name                      string        `xml:"Name,omitempty"`
    Email                     string        `xml:"Email,omitempty"`
    MustChangePassword        bool          `xml:"MustChangePassword,omitempty"`
    ActiveFlag                bool          `xml:"ActiveFlag,omitempty"`
    ChallengePhrase           string        `xml:"ChallengePhrase,omitempty"`
    ChallengeAnswer           string        `xml:"ChallengeAnswer,omitempty"`
    UserPermissions           []*UserAccess `xml:"UserPermissions,omitempty"`
    Delete                    int32         `xml:"Delete,omitempty"`
    LastSuccessfulLogin       time.Time     `xml:"LastSuccessfulLogin,omitempty"`
    IsAPIUser                 bool          `xml:"IsAPIUser,omitempty"`
    NotificationEmailAddress  string        `xml:"NotificationEmailAddress,omitempty"`
    IsLocked                  bool          `xml:"IsLocked,omitempty"`
    Unlock                    bool          `xml:"Unlock,omitempty"`
    BusinessUnit              int32         `xml:"BusinessUnit,omitempty"`
    DefaultBusinessUnit       int32         `xml:"DefaultBusinessUnit,omitempty"`
    DefaultApplication        string        `xml:"DefaultApplication,omitempty"`
    Locale                    *Locale       `xml:"Locale,omitempty"`
    TimeZone                  *TimeZone     `xml:"TimeZone,omitempty"`
    DefaultBusinessUnitObject *BusinessUnit `xml:"DefaultBusinessUnitObject,omitempty"`

    AssociatedBusinessUnits struct {
        BusinessUnit []*BusinessUnit `xml:"BusinessUnit,omitempty"`
    } `xml:"AssociatedBusinessUnits,omitempty"`

    Roles struct {
        Role []*Role `xml:"Role,omitempty"`
    } `xml:"Roles,omitempty"`

    LanguageLocale *Locale `xml:"LanguageLocale,omitempty"`

    SsoIdentities struct {
        SsoIdentity []*SsoIdentity `xml:"SsoIdentity,omitempty"`
    } `xml:"SsoIdentities,omitempty"`
}

调用SOAP的方法是:

func (s *SOAPClient) Call(soapAction string,request,response interface{}) error {
    envelope := SOAPEnvelope{
    //Header:        SoapHeader{},}

    envelope.Body.Content = request
    buffer := new(bytes.Buffer)

    encoder := xml.NewEncoder(buffer)
    //encoder.Indent("  ","    ")

    if err := encoder.Encode(envelope); err != nil {
        return err
    }

    if err := encoder.Flush(); err != nil {
        return err
    }

    log.Println(buffer.String())

    req,err := http.NewRequest("POST",s.url,buffer)
    if err != nil {
        return err
    }
    if s.auth != nil {
        req.SetBasicAuth(s.auth.Login,s.auth.Password)
    }

    req.Header.Add("Content-Type","text/xml; charset="utf-8"")
    if soapAction != "" {
        req.Header.Add("SOAPAction",soapAction)
    }

    req.Header.Set("User-Agent","gowsdl/0.1")
    req.Close = true

    tr := &http.Transport{
        TLSClientConfig: &tls.Config{
            InsecureSkipVerify: s.tls,},Dial: dialTimeout,}

    client := &http.Client{Transport: tr}
    res,err := client.Do(req)
    if err != nil {
        return err
    }
    defer res.Body.Close()

    rawbody,err := ioutil.ReadAll(res.Body)
    if err != nil {
        return err
    }
    if len(rawbody) == 0 {
        log.Println("empty response")
        return nil
    }

    log.Println(string(rawbody))
    respEnvelope := new(SOAPEnvelope)
    respEnvelope.Body = SOAPBody{Content: response}
    err = xml.Unmarshal(rawbody,respEnvelope)
    if err != nil {
        return err
    }

    fault := respEnvelope.Body.Fault
    if fault != nil {
        return fault
    }

    return nil
}

我已经将包导入到我的go文件中,并且喜欢如何调用它的指针.

要使用生成的代码,您显然必须首先使用生成的“构造函数”函数NewSOAPClient或NewSOAPClientWithTLSConfig初始化soap客户端.

之后,您需要准备两个可用作Call方法的请求和响应参数的值,它们表示soap请求/响应有效负载的正文内容.

这两个值的类型取决于您要进行的调用类型,例如假设调用create_account,update_account和delete_account通常需要不同的类型.基本上,请求值的类型应该可以编组到一个xml中,该xml与soap服务为指定操作所期望的xml相匹配,并且响应的类型应该是从xml中可解组的,该xml与soap服务的指定响应相匹配行动.

考虑这个人为的例子:

有一个允许您创建用户的SOAP服务.为了能够使用该服务创建用户,它需要您发送电子邮件和密码,如果一切正常,它将返回一个ID.在这种情况下,您的两个请求/响应类型将如下所示:

type CreateUserRequest struct {
    Email    string `xml:"Email,omitempty"`
    Password string `xml:"Password,omitempty"`
}

type CreateUserResponse struct {
    ID string `xml:"ID"`
}

然后客户端代码看起来像这样:

client := NewSOAPClient("https://soap.example.com/call",true,nil)

req := &CreateUserRequest{
    Email:    "jdoe@example.com",Password: "1234567890",}
res := &CreateUserResponse{}
if err := client.Call("create_user",req,res); err != nil {
    panic(err)
}

// if everything went well res.ID should have its
// value set with the one returned by the service.
fmt.Println(res.ID)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读