在围棋WSDL / SOAP支持?(WSDL/SOAP support on Go?)

2019-06-26 16:21发布

是否有支持对围棋SOAP / WSDL任何包?

Answer 1:

不。

SOAP吸收,但我不得不实现使用SOAP一个已定义的协议的服务器,所以我听取net/http ,并用解码/编码信封encoding/xml 。 在几分钟的时间,我已经担任我一起去第一包膜。



Answer 2:

没有沉迷于WSDL支持。 在其他语言的支持是静态或动态的:要么结构是预先生成从WSDL,或者它与哈希表飞完成。

你可以,但是,编码和解码手动SOAP请求。 我发现,标准encoding/xml包是不充分的SOAP。 有在不同的服务器上那么多的怪癖,并在限制encoding/xml难以生成请求这些服务器很满意。

例如,某些服务器需要xsi:type="xsd:string"每个字符串标记。 为了做到这一点正确的结构需要像这样的encoding/xml

type MethodCall struct {
    One XSI
    Two XSI
}

type XSI struct {
    Type string `xml:"xsi:type,attr"`
    Vaue string `xml:",chardata"`
}

而你建立这样的:

MethodCall{
    XSI{"xsd:string", "One"},
    XSI{"xsd:string", "Two"},
}

它给你:

<MethodCall>
    <One xsi:type="xsd:string">One</One>
    <Two xsi:type="xsd:string">Two</Two>
</MethodCall>

现在,这可能是好的。 这肯定能够完成任务。 但是,如果你需要什么样的不仅仅是更多的stringencoding/xml目前不支持interface{}

正如你可以看到这个变得复杂。 如果你有一个SOAP API进行整合,这可能不会是太糟糕了。 如果你有几个,每个都有自己的怪癖?

那岂不是很好,如果你可以只做到这一点?

type MethodCall struct {
    One string
    Two string
}

然后说给encoding/xml :“此服务器需要XSI的类型”。

为了解决这个问题,我创建github.com/webconnex/xmlutil 。 这是一项正在进行的工作。 它不具有的所有功能encoding/xml的编码器/解码器,但它有什么是需要SOAP。

这里有一个工作示例:

package main

import (
    "bytes"
    "encoding/xml"
    "fmt"
    "github.com/webconnex/xmlutil"
    "log"
    //"net/http"
)

type Envelope struct {
    Body `xml:"soap:"`
}

type Body struct {
    Msg interface{}
}

type MethodCall struct {
    One string
    Two string
}

type MethodCallResponse struct {
    Three string
}

func main() {
    x := xmlutil.NewXmlUtil()
    x.RegisterNamespace("http://www.w3.org/2001/XMLSchema-instance", "xsi")
    x.RegisterNamespace("http://www.w3.org/2001/XMLSchema", "xsd")
    x.RegisterNamespace("http://www.w3.org/2003/05/soap-envelope", "soap")
    x.RegisterTypeMore(Envelope{}, xml.Name{"http://www.w3.org/2003/05/soap-envelope", ""},
        []xml.Attr{
            xml.Attr{xml.Name{"xmlns", "xsi"}, "http://www.w3.org/2001/XMLSchema-instance"},
            xml.Attr{xml.Name{"xmlns", "xsd"}, "http://www.w3.org/2001/XMLSchema"},
            xml.Attr{xml.Name{"xmlns", "soap"}, "http://www.w3.org/2003/05/soap-envelope"},
        })
    x.RegisterTypeMore("", xml.Name{}, []xml.Attr{
        xml.Attr{xml.Name{"http://www.w3.org/2001/XMLSchema-instance", "type"}, "xsd:string"},
    })

    buf := new(bytes.Buffer)
    buf.WriteString(`<?xml version="1.0" encoding="utf-8"?>`)
    buf.WriteByte('\n')
    enc := x.NewEncoder(buf)
    env := &Envelope{Body{MethodCall{
        One: "one",
        Two: "two",
    }}}
    if err := enc.Encode(env); err != nil {
        log.Fatal(err)
    }
    // Print request
    bs := buf.Bytes()
    bs = bytes.Replace(bs, []byte{'>', '<'}, []byte{'>', '\n', '<'}, -1)
    fmt.Printf("%s\n\n", bs)

    /*
        // Send response, SOAP 1.2, fill in url, namespace, and action
        var r *http.Response
        if r, err = http.Post(url, "application/soap+xml; charset=utf-8; action="+namespace+"/"+action, buf); err != nil {
            return
        }
        dec := x.NewDecoder(r.Body)
    */
    // Decode response
    dec := x.NewDecoder(bytes.NewBufferString(`<?xml version="1.0" encoding="utf-8"?>
    <soap:Envelope>
        <soap:Body>
            <MethodCallResponse>
                <Three>three</Three>
            </MethodCallResponse>
        </soap:Body>
    </soap:Envelope>`))
    find := []xml.Name{
        xml.Name{"", "MethodCallResponse"},
        xml.Name{"http://www.w3.org/2003/05/soap-envelope", "Fault"},
    }
    var start *xml.StartElement
    var err error
    if start, err = dec.Find(find); err != nil {
        log.Fatal(err)
    }
    if start.Name.Local == "Fault" {
        log.Fatal("Fault!") // Here you can decode a Soap Fault
    }
    var resp MethodCallResponse
    if err := dec.DecodeElement(&resp, start); err != nil {
        log.Fatal(err)
    }
    fmt.Printf("%#v\n\n", resp)
}

通过以上的例子中,我使用的Find方法来获取响应对象,或故障。 这不是绝对必要的。 你也可以像下面这样做:

x.RegisterType(MethodCallResponse{})
...
// Decode response
dec := x.NewDecoder(bytes.NewBufferString(`<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope>
    <soap:Body>
        <MethodCallResponse>
            <Three>three</Three>
        </MethodCallResponse>
    </soap:Body>
</soap:Envelope>`))
var start *xml.StartElement
var resp Envelope
if err := dec.DecodeElement(&resp, start); err != nil {
    log.Fatal(err)
}
fmt.Printf("%#v\n\n", resp)

你会找到Find方法有用的,当你的数据是这样的:

<soap:Envelope>
  <soap:Body>
    <MethodResponse>
      <MethodResult>
        <diffgr:diffgram>
          <NewDataSet>
            <Table1 diffgr:id="Table1" msdata:rowOrder="0" diffgr:hasChanges="inserted">
              <Three>three</Three>
            </Table1>
          </NewDataSet>
        </diffgr:diffgram>
      </MethodResult>
    </MethodResponse>
  </soap:Body>
</soap:Envelope>

这是一个DiffGram,微软.NET的一部分。 您可以使用Find方法来获得Table1 。 该DecodeDecodeElement方法也适用于片。 所以,你可以在通过[]MethodCallResponse如果NewDataSet恰好包含多个结果。

我确实与Zippower同意,SOAP不吸。 但不幸的是很多企业使用SOAP,而你有时不得不使用这些API。 随着xmlutil包我希望让它少一点痛苦的工作。



Answer 3:

虽然还是有没有在围棋本身,有gowsdl 。 到目前为止,似乎工作不够好,我与几个SOAP服务接口。

我不使用SOAP代理提供,我相信不支持AUTH,但gowsdl生成我从WSDL需要编组请求和响应数据编的结构和代码-一个巨大的胜利。



Answer 4:

还有一个WSDL-GO 。
但我没有用它,所以我真的不能说。



Answer 5:

一个选择是使用gSOAP的产生一个C WSDL客户端,然后通过GO使用该客户端与CGO



文章来源: WSDL/SOAP support on Go?