2012-12-12 73 views
2

我有一個soap 1.1/1.2 web服務我試圖使用suds訪問。使用泡沫訪問響應肥皂標題

不幸的是,該服務將身份驗證令牌放入響應SOAP頭中。

是否有可能以某種方式訪問​​標題?

我知道可以在請求中設置一個自定義肥皂標題,但那不是我要找的。

回答

2

你可以做這樣的事情

print client.last_received().getChild("soap:Envelope").getChild("soap:Header") 
.getChild("ResponseHeader").getChild("resultCode").getText() 

上面寫明在SOAP頭字段resultCode爲。你必須爲每個領域做到這一點。就我所知,這是一個後門,可以讀取標題。

詳情看soap headers with suds

+0

乾杯!我想一個更清潔的方法是:'client.last_received()getChildAtPath( 「肥皂:信封/ SOAP:頁眉/ ResponseHeader/resultCode爲」)。gettext的()',但仍覺得笨重。 – soulcheck

+0

耶同意了。我以前沒有使用..AtPath。乾淨 – fayyazkl

4

我一直在使用(仍保持)無泡沫jurko分支,遇到了麻煩,因爲client.last_received()除去它分叉後早期。所以我不得不找出一種替代方法來訪問標題。

幸運的是,您可以使用消息插件來存儲解析的文檔,然後通過插件訪問頭文件。爲了更加方便,您可以不使用xml文檔中的原始值來處理基於service-method的頭文件,以獲得正確的類型化/結構化值。

from suds.plugin import MessagePlugin 

class HeaderPlugin(MessagePlugin): 
    def __init__(self): 
     self.document = None 

    def parsed(self, context): 
     self.document = context.reply 

    def get_headers(self, method): 
     method = method.method 
     binding = method.binding.output 
     rtypes = binding.headpart_types(method, False) 

     envns = ('SOAP-ENV', 'http://schemas.xmlsoap.org/soap/envelope/') 
     soapenv = self.document.getChild('Envelope', envns) 
     soapheaders = soapenv.getChild('Header', envns) 
     nodes = soapheaders.children 
     if len(nodes): 
      resolved = rtypes[0].resolve(nobuiltin=True) 
      return binding.unmarshaller().process(nodes[0], resolved) 
     return None 

用法:

from suds.client import Client 

hp = HeaderPlugin() 
client = Client(wsdl, plugins=[hp]) 

response = client.service.LoremIpsum() 
headers = hp.get_headers(client.service.LoremIpsum) 

輸出示例:

>>> headers 
(AuthenticationResponseHeader){ 
    sessionKey = "a631cd00-c6be-416f-9bd3-dbcd322e0848" 
    validUntil = 2030-01-01 01:01:01.123456+01:00 
} 
>>> headers.validUntil 
datetime.datetime(2030, 1, 1, 1, 1, 1, 123456, tzinfo=<suds.sax.date.FixedOffsetTimezone object at 0x7f7347856be0>) 
+0

你先生,救了我一捆時間。我的感謝! –

0

的TOWR的類插件效果很好,但是當你在SOAPHEADER響應一個以上的OBJ它有一個問題。 他的代碼只獲取第一個對象。

下面是代碼,以改善TOWR的類:

class HeaderPlugin(MessagePlugin): 
    def __init__(self): 
     self.document = None 

    def parsed(self, context): 
     self.document = context.reply 

    def get_headers(self, method): 
     Result = {} 
     method = method.method 
     binding = method.binding.output 
     SHeaderElem = binding.headpart_types(method, False) 

     envns = ('SOAP-ENV', 'http://schemas.xmlsoap.org/soap/envelope/') 
     soapenv = self.document.getChild('Envelope', envns) 
     soapheaders = soapenv.getChild('Header', envns) 
     SHeaderNodes = soapheaders.children 

     for Elem in SHeaderElem: 
      for Node in SHeaderNodes: 
       if(Node.name == Elem.name): 
        ElemRes = Elem.resolve(nobuiltin=True) 
        NodeRes = binding.unmarshaller().process(Node, ElemRes) 
        Result[Elem.name] = NodeRes 
     return Result 
    # 

爲了更好的理解,看到的例子。 如果你收到此SOAP響應:

<soap-env:Envelope xmlns:eb="http://www.ebxml.org/namespaces/messageHeader" xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/12/secext"> 
    <soap-env:Header> 
     <eb:MessageHeader eb:version="1.0" soap-env:mustUnderstand="1"> 
      <!-- --> 
     </eb:MessageHeader> 
     <wsse:Security> 
      <!-- --> 
     </wsse:Security> 
    </soap-env:Header> 
    <soap-env:Body> 
     <!-- --> 
    </soap-env:Body> 
</soap-env:Envelope> 

功能get_headers將返回一個字典是這樣的:

SoapHeadersResp = {'MessageHeader':MessageHeaderObj, 'Security':SecurityObj} 

要使用這個類只是遵循TOWR說相同的步驟,替換他的HeaderPlugin類與這一個。