2012-08-01 13 views
16

मैंने चारों ओर देखा और मुझे लगता है कि एक्सएमएल के लिए समर्थन है।डब्ल्यूएसडीएल/एसओएपी समर्थन गो पर?

क्या गो पर SOAP/WSDL का समर्थन करने के लिए कोई पैकेज हैं?

+0

छोटे एक्सएमएल/एसओएपी पैकेज के लिए धन्यवाद, नौकरी अच्छी तरह से किया। दोस्तों को यहां lib मिल सकता है - https://github.com/webconnex/xmlutil – Knights

+0

मुझे अक्सर विरासत प्रणाली पर SOAP का उपयोग करना पड़ता है, और पिछले सप्ताहांत तक हार्ड कोडिंग संरचनाओं द्वारा इसे किया जा रहा है। डब्ल्यूएसडीएल के लिए एक पार्सर + गो कोड जनरेटर हैक किया गया है जो SOAP को कॉल करने के लिए उपयोग योग्य गो कोड का उत्पादन कर सकता है। मेरे द्वारा उपयोग किए जाने वाले कुछ एपीआई काफी व्यापक हैं, 2k LOC से अधिक फ़ाइलों को उत्पन्न करते हैं। इसे जांचें: https://github.com/fiorix/wsdl2go – fiorix

उत्तर

11

नहीं।

सोप बेकार है, लेकिन मैं पहले से ही एक-निर्धारित प्रोटोकॉल सोप का उपयोग करता है की एक सर्वर को लागू करने के लिए किया था, तो मैं net/http साथ सुना और encoding/xml साथ डीकोड/इनकोडिंग लिफाफे। कुछ ही मिनटों में, मैंने पहले ही गो के साथ अपना पहला लिफाफा पेश किया है।

+1

निश्चित रूप से करता है, लेकिन एंटरप्राइज़ सिस्टम की अनंतता है जो केवल SOAP का समर्थन करती है। उन मामलों के लिए, हमें अभी भी कुछ उपयोगी चाहिए। – fiorix

17

गो में डब्लूएसडीएल के लिए समर्थन नहीं है। अन्य भाषाओं में समर्थन या तो स्थैतिक या गतिशील हैं: या तो स्ट्रक्चर डब्लूएसडीएल से पूर्व-उत्पन्न होते हैं, या यह हैश टेबल के साथ फ्लाई पर किया जाता है।

हालांकि, आप मैन्युअल रूप से एसओएपी अनुरोधों को एन्कोड और डीकोड कर सकते हैं। मैंने पाया कि मानक encoding/xml पैकेज SOAP के लिए अपर्याप्त होना है। विभिन्न सर्वरों में इतने सारे क्विर्क हैं, और encoding/xml में सीमाएं इन सर्वरों से अनुरोध करने में एक समस्या उत्पन्न करती हैं।

उदाहरण के लिए, कुछ सर्वरों को प्रत्येक स्ट्रिंग टैग पर xsi:type="xsd:string" की आवश्यकता होती है। आदेश में इस को ठीक से अपने struct करने के लिए encoding/xml के लिए इस तरह देखने के लिए की जरूरत है:

type MethodCall struct { 
    One XSI 
    Two XSI 
} 

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

और आप इसे इस तरह का निर्माण:

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

अब इस:

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

जो तुम देता है ठीक हो सकता है यह निश्चित रूप से काम पूरा हो जाता है। लेकिन क्या होगा यदि आपको केवल string से अधिक की आवश्यकता है? encoding/xml वर्तमान में interface{} का समर्थन नहीं करता है।

जैसा कि आप देख सकते हैं कि यह जटिल हो जाता है। यदि आपके पास एकीकृत करने के लिए एक एसओएपी एपीआई था, तो शायद यह बहुत बुरा नहीं होगा। क्या होगा यदि आपके पास कई थे, प्रत्येक अपने स्वयं के quirks के साथ?

क्या यह अच्छा नहीं होगा अगर आप ऐसा कर सकें?

type MethodCall struct { 
    One string 
    Two string 
} 

फिर encoding/xml को कहते हैं: "यह सर्वर चाहते xsi प्रकार"।

इस समस्या को हल करने के लिए मैंने github.com/webconnex/xmlutil बनाया। यह एक काम प्रगति पर है। इसमें encoding/xml के एन्कोडर/डिकोडर की सभी सुविधाएं नहीं हैं, लेकिन एसओएपी के लिए इसकी आवश्यकता है।

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, Microsoft .NET का हिस्सा है।Table1 पर जाने के लिए आप Find विधि का उपयोग कर सकते हैं। Decode और DecodeElement विधि स्लाइस पर भी काम करता है। तो में NewDataSet में एक से अधिक परिणाम होने पर आप पास कर सकते हैं।

मैं ज़िप्पर से सहमत हूं कि SOAP चूसता है। लेकिन दुर्भाग्यवश बहुत से उद्यम SOAP का उपयोग करते हैं, और आपको कभी-कभी इन API का उपयोग करने के लिए मजबूर किया जाता है। Xmlutil पैकेज के साथ मैं काम करने के लिए थोड़ा कम दर्दनाक बनाने की उम्मीद करता हूं।

+6

गो टिप अब [मंगल ग्रह] का समर्थन करता है (http://tip.golang.org/pkg/encoding/xml/#Marshaler) और [Unmarshalers] (http://tip.golang.org/pkg/encoding/xml/# Unmarshaler) एन्कोडिंग/एक्सएमएल जैसे एन्कोडिंग/जेसन में पहले से ही किया गया है, और यह सुविधा गो 1.2 में होने की उम्मीद है। यह SOAP को संभालने में मदद कर सकता है। – Matt

+0

महान @luke, आपकी छोटी एक्सएमएल उपयोगिता lib ... काम करता है, मुझे दस्तावेज शुरू करने की आवश्यकता होती है, हालांकि उपरोक्त स्क्रिप्ट के माध्यम से स्कैनिंग के कुछ मिनटों के साथ मैं समझने में सक्षम था कि चीजें – Knights

+0

पर कैसे जाना है, मैंने एक डब्लूएसडीएल पार्सर लिखा है SOAP कॉल करने के लिए जाओ कोड उत्पन्न करें। टैग के संबंध में एन्कोडिंग/एक्सएमएल में बहुत सी सीमाएं हैं, और मैंने इसे रीडमे में एक लिंक दिया है। इसे देखें: https://github.com/fiorix/wsdl2go – fiorix

-1

बेस्ट विकल्प gsoap जो एक सी डबल्यूएसडीएल ग्राहक पैदा करता है का उपयोग करने के लिए और फिर वहाँ अभी भी जाओ अपने आप में कुछ भी नहीं है जबकि cgo

+1

मैं "सर्वश्रेष्ठ विकल्प" पर पुनर्विचार करूंगा! यह एक जटिल और भ्रमित दृष्टिकोण है – Arman

+0

gsoap शायद सबसे स्थिर और पूर्ण साबुन कार्यान्वयन उपलब्ध है: यदि आप गो से सी/सी ++ का उपयोग करने की परेशानी का काम कर सकते हैं ... तो इसका रास्ता है :) कोई पन इरादा नहीं – eddyce

5

के साथ जाने के माध्यम से है कि ग्राहक का उपयोग है, वहाँ gowsdl है। अब तक, ऐसा लगता है कि कई एसओएपी सेवाओं के साथ इंटरफेस करने के लिए मेरे लिए काफी अच्छा काम है।

मैं एसओएपी प्रॉक्सी का उपयोग नहीं करता, जो मुझे विश्वास है कि यह समर्थन नहीं करता है, लेकिन gowsdl डब्लूएसडीएल से मार्शल अनुरोधों और अनमर्शल प्रतिक्रियाओं के लिए आवश्यक स्ट्रक्चर और कोड उत्पन्न करता है - एक बड़ी जीत।

0

wsdl-go भी है।
लेकिन मैंने इसका उपयोग नहीं किया है, इसलिए मैं वास्तव में नहीं कह सकता।

+0

ऐसा प्रतीत नहीं होता है। –

 संबंधित मुद्दे