2015-03-03 93 views
2

根據特定的WSDL實現WebService。客戶端無法更改。正確處理來自客戶端的請求,但客戶端因爲變量中的名稱空間而抱怨響應。從Spyne響應變量中刪除命名空間

我想要什麼(基於WSDL的soapUI響應):

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:cal="http://callback.foo.com/"> 
    <soapenv:Header/> 
    <soapenv:Body> 
     <cal:foo_statusResponse> 
     <result>SUCCESS</result> 
     <notify>Thanks!</notify> 
     </cal:foo_statusResponse> 
    </soapenv:Body> 
</soapenv:Envelope> 

什麼我收到(通知tns:的變量造成驗證問題):

<senv:Envelope xmlns:tns="http://callback.foo.com/" xmlns:senv="http://schemas.xmlsoap.org/soap/envelope/"> 
    <senv:Body> 
    <tns:foo_statusResponse> 
     <tns:result>SUCCESS</tns:result> 
     <tns:notify>Thanks!</tns:notify> 
    </tns:foo_statusResponse> 
    </senv:Body> 
</senv:Envelope> 

Java客戶端拋出此例外:

[com.sun.istack.SAXParseException2; lineNumber:2; columnNumber:162; 意外元素(URI:「http://callback.foo.com/」,本地:「結果」)。 預期元件< {}結果>,< {}通知>]

執行代碼段:

class fooStatusRS(ComplexModel): 
    result = Unicode() 
    notify = Unicode() 

class foo_callback(ServiceBase): 
    @srpc(Unicode, Unicode, Unicode, Unicode, statusbarInfo, anotherResponse, 
      _out_header=None, 
      _out_variable_names=("result", "notify"), 
      _returns=(Unicode, Unicode), 
      _out_message_name="foo_statusResponse", 
      _operation_name="foo_status_rq") 
    def foo_status(foo_id, reply, ref, status, statusbar, another): 
     if foo_id: 
      print foo_id 

     return fooStatusRS(result="SUCCESS", notify="Foo received!") 

回答

1

這是不可能的(還),並通過在一個類似的問題here被回答維護者。

解決的辦法是向「method_return_string」的event_manager添加監聽器,然後執行一些字符串操作。

def _method_return_string(ctx): 
    ctx.out_string[0] = ctx.out_string[0].replace("tns:result>", "result>") 
    ctx.out_string[0] = ctx.out_string[0].replace("tns:notify>", "notify>") 
0

它可以通過覆蓋在nsmap application.interface

def fix_nsmap(application): 
     conversion_dict = { 
      'tns': None, 
      'senv': 'soap', 
     } 
     nsmap = application.interface.nsmap 
     for k, v in conversion_dict.iteritems(): 
      nsmap[v] = nsmap[k] 
      del nsmap[k] 

     application.interface.nsmap = nsmap 

    application_security2 = Application(
     [Security2Service], 
     tns=NS, 
     name='Security2', 
     in_protocol=Soap11(), 
     out_protocol=Soap11() 
    ) 

    fix_nsmap(application_security2) 

nsmap [無]設置的默認NS

+0

application.interface is deprecated synce at least 2.10:http://spyne.io/docs/2.10/reference/application.html – blueCat 2016-10-13 15:44:41

+0

它沒有https://github.com/arskom/spyne/blob/master /spyne/application.py#L107 – thebat 2016-12-02 11:33:00

0

固定如果你想知道如何監聽器添加到event_manager爲method_return_string,見下面一個完整的例子:

from spyne import Application, rpc, ServiceBase, Iterable, Integer, Unicode 

from spyne.protocol.soap import Soap11 
from spyne.server.wsgi import WsgiApplication 


class HelloWorldService(ServiceBase): 
    @rpc(Unicode, Integer, _returns=Iterable(Unicode)) 
    def say_hello(ctx, name, times): 
     for i in range(times): 
      yield u'Hello, %s' % name 


def on_method_return_string(ctx): 
    ctx.out_string[0] = ctx.out_string[0].replace(b'Hello>', b'Good by') 

HelloWorldService.event_manager.add_listener('method_return_string', 
               on_method_return_string) 

application = Application([HelloWorldService], 'spyne.examples.hello.soap', 
          in_protocol=Soap11(validator='lxml'), 
          out_protocol=Soap11()) 

wsgi_application = WsgiApplication(application) 


if __name__ == '__main__': 
    import logging 

    from wsgiref.simple_server import make_server 
    server = make_server('127.0.0.1', 8000, wsgi_application) 
    server.serve_forever() 

截至Spyne 2.12這仍然是關於用來從響應變量中刪除名稱空間的方法。