跳转到主要内容

在Zope 2中使用ZSI进行SOAP

项目描述

SOAP支持

此SOAP实现允许您为对象提供SOAP视图。SOAP层基于ZSI

此包需要ZSI 2.0或更高版本。

SOAP支持的实现方式与标准Zope XML-RPC支持非常相似。要通过SOAP调用方法,您需要创建和注册SOAP视图。

版本 >= 0.5.4旨在与Zope 2.13及更高版本一起使用。较旧版本(0.5.3及以下)应能与Zope < 2.13正确工作

此包在很大程度上受到Zope 3 SOAP(http://svn.zope.org/soap)的启发。

让我们编写一个简单的SOAP视图,它回显各种类型的输入

>>> import ZSI
>>> from Products.Five import BrowserView
>>> class EchoView(BrowserView):
...
...     def echoString(self, value):
...         return value
...
...     def echoStringArray(self, value):
...         return value
...
...     def echoInteger(self, value):
...         return value
...
...     def echoIntegerArray(self, value):
...         return value
...
...     def echoFloat(self, value):
...         return value
...
...     def echoFloatArray(self, value):
...         return value
...
...     def echoStruct(self, value):
...         return value
...
...     def echoStructArray(self, value):
...         return value
...
...     def echoVoid(self):
...         return
...
...     def echoBase64(self, value):
...         import base64
...         return base64.encodestring(value)
...
...     def echoDate(self, value):
...         import time
...         return time.gmtime(time.mktime(value))
...
...     def echoDecimal(self, value):
...         return value
...
...     def echoBoolean(self, value):
...         return value
...
...     def ValidateEmailRequest(self, requestData, response):
...         mail = requestData._Email
...         response._Status = '%s is OK' % mail
...         return response
...
...     def testFault(self):
...         raise ZSI.Fault(ZSI.Fault.Client, "Testing the zsi fault")

现在我们将将其注册为SOAP视图。目前,我们只将视图注册到文件夹对象,并在根文件夹上调用它

>>> from zope.configuration import xmlconfig
>>> ignored = xmlconfig.string("""
... <configure
...     xmlns="http://namespaces.zope.org/zope"
...     xmlns:browser="http://namespaces.zope.org/browser"
...     xmlns:soap="http://namespaces.zope.org/soap"
...     >
...
...   <!-- We only need to do this include in this example,
...        Normally the include has already been done for us. -->
...
...   <include package="z3c.soap" file="meta.zcml" />
...   <include package="Products.Five" file="meta.zcml" />
...   <include package="z3c.soap"/>
...
...   <soap:view
...       for="OFS.interfaces.IFolder"
...       methods="echoString echoStringArray echoInteger echoIntegerArray
...                echoFloat echoFloatArray echoStruct echoVoid echoBase64
...                echoDate echoDecimal echoBoolean ValidateEmailRequest
...                testFault"
...       class="z3c.soap.README.EchoView"
...       permission="zope2.SOAPAccess"
...       />
...
...   <utility
...       factory="z3c.soap.tests.mailvalidation.validateEmailIn"
...       name="ValidateEmailRequest"
...       provides="z3c.soap.interfaces.IZSIRequestType"/>
...
...   <utility
...       factory="z3c.soap.tests.mailvalidation.validateEmailOut"
...       name="ValidateEmailRequest"
...       provides="z3c.soap.interfaces.IZSIResponseType"/>
...
...
... </configure>
... """)

然后调用我们的SOAP方法

>>> from Testing.ZopeTestCase import user_name, user_password
>>> self.setRoles(['Manager'])
>>> print http(r"""
... POST /test_folder_1_ HTTP/1.0
... Authorization: Basic %s:%s
... Content-Length: 102
... Content-Type: text/xml
... SOAPAction: /
...
... <?xml version="1.0"?>
... <SOAP-ENV:Envelope
...  SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
...  xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
...  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
...  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
...  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
...  <SOAP-ENV:Body>
...    <m:echoString xmlns:m="http://www.soapware.org/">
...      <arg1 xsi:type="xsd:string">hello</arg1>
...    </m:echoString>
...  </SOAP-ENV:Body>
... </SOAP-ENV:Envelope>
... """ % (user_name, user_password), handle_errors=True)
HTTP/1.0 200 OK
Content-Length: ...
Content-Type: text/xml
<BLANKLINE>
...hello...

请注意,如果我们不提供认证凭据,则会收到未经授权的错误,因为我们注册视图时用ManageContent权限保护了它

>>> self.logout()
>>> print http(r"""
... POST /test_folder_1_ HTTP/1.0
... Content-Length: 102
... Content-Type: text/xml
... SOAPAction: /
...
... <?xml version="1.0"?>
... <SOAP-ENV:Envelope
...  SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
...  xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
...  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
...  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
...  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
...  <SOAP-ENV:Body>
...    <m:echoString xmlns:m="http://www.soapware.org/">
...      <arg1 xsi:type="xsd:string">hello</arg1>
...    </m:echoString>
...  </SOAP-ENV:Body>
... </SOAP-ENV:Envelope>
... """)
HTTP/1.0 401 Unauthorized
Content-Length: ...
Content-Type: text/xml
Www-Authenticate: basic realm="Zope2"
<BLANKLINE>
<SOAP-ENV:Envelope xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ZSI="http://www.zolera.com/schemas/ZSI/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><SOAP-ENV:Header></SOAP-ENV:Header><SOAP-ENV:Body><SOAP-ENV:Fault><faultcode>SOAP-ENV:Server</faultcode><faultstring>Not authorized</faultstring></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>

参数

SOAP视图可以接受ZSI可以理解的任何参数。以下演示了使用基本SOAP定义的数据类型

>>> print http(r"""
... POST /test_folder_1_ HTTP/1.0
... Authorization: Basic %s:%s
... Content-Length: 102
... Content-Type: text/xml
... SOAPAction: /
...
... <?xml version="1.0"?>
... <SOAP-ENV:Envelope
...  SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
...  xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
...  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
...  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
...  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
...  <SOAP-ENV:Body>
...    <m:echoString xmlns:m="http://www.soapware.org/">
...      <arg1 xsi:type="xsd:string">hello</arg1>
...    </m:echoString>
...  </SOAP-ENV:Body>
... </SOAP-ENV:Envelope>
... """ % (user_name, user_password))
HTTP/1.0 200 OK
Content-Length: ...
Content-Type: text/xml...
<BLANKLINE>
...hello...
>>> print http(r"""
... POST /test_folder_1_ HTTP/1.0
... Authorization: Basic %s:%s
... Content-Length: 102
... Content-Type: text/xml
... SOAPAction: /
...
... <?xml version="1.0"?>
... <SOAP-ENV:Envelope
...  SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
...  xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
...  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
...  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
...  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
...  <SOAP-ENV:Body>
...    <m:echoStringArray xmlns:m="http://www.soapware.org/">
...    <param SOAP-ENC:arrayType="xsd:ur-type[4]" xsi:type="SOAP-ENC:Array">
...    <item xsi:type="xsd:string">one</item>
...    <item xsi:type="xsd:string">two</item>
...    <item xsi:type="xsd:string">three</item>
...    <item xsi:type="xsd:string">four</item>
...    </param>
...    </m:echoStringArray>
...  </SOAP-ENV:Body>
... </SOAP-ENV:Envelope>
... """ % (user_name, user_password))
HTTP/1.0 200 OK
Content-Length: ...
Content-Type: text/xml...
<BLANKLINE>
...one...two...three...four...
>>> print http(r"""
... POST /test_folder_1_ HTTP/1.0
... Authorization: Basic %s:%s
... Content-Length: 102
... Content-Type: text/xml
... SOAPAction: /
...
... <?xml version="1.0"?>
... <SOAP-ENV:Envelope
...  SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
...  xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
...  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
...  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
...  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
...  <SOAP-ENV:Body>
...    <m:echoInteger xmlns:m="http://www.soapware.org/">
...      <arg1 xsi:type="xsd:int">42</arg1>
...    </m:echoInteger>
...  </SOAP-ENV:Body>
... </SOAP-ENV:Envelope>
... """ % (user_name, user_password))
HTTP/1.0 200 OK
Content-Length: ...
Content-Type: text/xml...
<BLANKLINE>
...42...
>>> print http(r"""
... POST /test_folder_1_ HTTP/1.0
... Authorization: Basic %s:%s
... Content-Length: 102
... Content-Type: text/xml
... SOAPAction: /
...
... <?xml version="1.0"?>
... <SOAP-ENV:Envelope
...  SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
...  xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
...  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
...  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
...  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
...  <SOAP-ENV:Body>
...    <m:echoIntegerArray xmlns:m="http://www.soapware.org/">
...    <param SOAP-ENC:arrayType="xsd:ur-type[4]" xsi:type="SOAP-ENC:Array">
...    <item xsi:type="xsd:int">1</item>
...    <item xsi:type="xsd:int">2</item>
...    <item xsi:type="xsd:int">3</item>
...    <item xsi:type="xsd:int">4</item>
...    </param>
...    </m:echoIntegerArray>
...  </SOAP-ENV:Body>
... </SOAP-ENV:Envelope>
... """ % (user_name, user_password))
HTTP/1.0 200 OK
Content-Length: ...
Content-Type: text/xml...
<BLANKLINE>
...1...2...3...4...

请注意,浮点数以xsd:decimal值返回

>>> print http(r"""
... POST /test_folder_1_ HTTP/1.0
... Authorization: Basic %s:%s
... Content-Length: 102
... Content-Type: text/xml
... SOAPAction: /
...
... <?xml version="1.0"?>
... <SOAP-ENV:Envelope
...  SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
...  xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
...  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
...  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
...  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
...  <SOAP-ENV:Body>
...    <m:echoFloat xmlns:m="http://www.soapware.org/">
...      <arg1 xsi:type="xsd:float">42.2</arg1>
...    </m:echoFloat>
...  </SOAP-ENV:Body>
... </SOAP-ENV:Envelope>
... """ % (user_name, user_password))
HTTP/1.0 200 OK
Content-Length: ...
Content-Type: text/xml
<BLANKLINE>
...xsi:type="xsd:float">42.200000</...

即使它们在浮点数组中

>>> print http(r"""
... POST /test_folder_1_ HTTP/1.0
... Authorization: Basic %s:%s
... Content-Length: 102
... Content-Type: text/xml
... SOAPAction: /
...
... <?xml version="1.0"?>
... <SOAP-ENV:Envelope
...  SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
...  xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
...  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
...  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
...  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
...  <SOAP-ENV:Body>
...    <m:echoFloatArray xmlns:m="http://www.soapware.org/">
...    <param SOAP-ENC:arrayType="xsd:ur-type[4]" xsi:type="SOAP-ENC:Array">
...    <item xsi:type="xsd:float">1.1</item>
...    <item xsi:type="xsd:float">2.2</item>
...    <item xsi:type="xsd:float">3.3</item>
...    <item xsi:type="xsd:float">4.4</item>
...    </param>
...    </m:echoFloatArray>
...  </SOAP-ENV:Body>
... </SOAP-ENV:Envelope>
... """ % (user_name, user_password))
HTTP/1.0 200 OK
Content-Length: ...
Content-Type: text/xml
<BLANKLINE>
...xsi:type="xsd:float">1.100000</...
...xsi:type="xsd:float">2.200000</...
...xsi:type="xsd:float">3.300000</...
...xsi:type="xsd:float">4.400000</...
>>> result = http(r"""
... POST /test_folder_1_ HTTP/1.0
... Authorization: Basic %s:%s
... Content-Length: 102
... Content-Type: text/xml
... SOAPAction: /
...
... <?xml version="1.0"?>
... <SOAP-ENV:Envelope
...  SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
...  xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
...  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
...  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
...  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
...  <SOAP-ENV:Body>
...    <m:echoStruct xmlns:m="http://www.soapware.org/">
...      <param>
...      <first xsi:type="xsd:string">first 1</first>
...      <last xsi:type="xsd:string">last 1</last>
...      </param>
...    </m:echoStruct>
...  </SOAP-ENV:Body>
... </SOAP-ENV:Envelope>
... """ % (user_name, user_password))
>>> result = str(result)
>>> assert(result.find('first 1') > -1)
>>> assert(result.find('last 1') > -1)

请注意,结构数组的数组(至少按照互操作性套件)似乎不起作用

>>> print http(r"""
... POST /test_folder_1_ HTTP/1.0
... Authorization: Basic %s:%s
... Content-Length: 102
... Content-Type: text/xml
... SOAPAction: /
...
... <?xml version="1.0"?>
... <SOAP-ENV:Envelope
...  SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
...  xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
...  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
...  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
...  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
...  xmlns:so="http://soapinterop.org/">
...  <SOAP-ENV:Body>
...    <m:echoStructArray xmlns:m="http://www.soapware.org/xsd">
...    <inputArray SOAP-ENC:arrayType="so:SOAPStruct[2]"
...                xsi:type="SOAP-ENC:Array">
...      <item xsi:type="so:SOAPStruct">
...      <varString xsi:type="xsd:string">str 1</varString>
...      <varInt xsi:type="xsd:int">1</varInt>
...      </item>
...      <item xsi:type="so:SOAPStruct">
...      <varString xsi:type="xsd:string">str 2</varString>
...      <varInt xsi:type="xsd:int">2</varInt>
...      </item>
...    </inputArray>
...    </m:echoStructArray>
...  </SOAP-ENV:Body>
... </SOAP-ENV:Envelope>
... """ % (user_name, user_password), handle_errors=True)
HTTP/1.0 500 Internal Server Error
Content-Length: ...
Content-Type: text/xml
<BLANKLINE>
<SOAP-ENV:Envelope ...
...
>>> print http(r"""
... POST /test_folder_1_ HTTP/1.0
... Authorization: Basic %s:%s
... Content-Length: 102
... Content-Type: text/xml
... SOAPAction: /
...
... <?xml version="1.0"?>
... <SOAP-ENV:Envelope
...  SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
...  xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
...  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
...  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
...  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
...  <SOAP-ENV:Body>
...    <m:echoVoid xmlns:m="http://www.soapware.org/">
...    </m:echoVoid>
...  </SOAP-ENV:Body>
... </SOAP-ENV:Envelope>
... """ % (user_name, user_password))
HTTP/1.0 200 OK
Content-Length: ...
Content-Type: text/xml
<BLANKLINE>
...echoVoidResponse...
>>> print http(r"""
... POST /test_folder_1_ HTTP/1.0
... Authorization: Basic %s:%s
... Content-Length: 102
... Content-Type: text/xml
... SOAPAction: /
...
... <?xml version="1.0"?>
... <SOAP-ENV:Envelope
...  SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
...  xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
...  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
...  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
...  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
...  <SOAP-ENV:Body>
...    <m:echoBase64 xmlns:m="http://www.soapware.org/">
...      <arg1 xsi:type="SOAP-ENC:base64">AAECAwQF</arg1>
...    </m:echoBase64>
...  </SOAP-ENV:Body>
... </SOAP-ENV:Envelope>
... """ % (user_name, user_password))
HTTP/1.0 200 OK
Content-Length: ...
Content-Type: text/xml...
<BLANKLINE>
...AAECAwQF...

日期时间似乎可以正常工作

>>> print http(r"""
... POST /test_folder_1_ HTTP/1.0
... Authorization: Basic %s:%s
... Content-Length: 102
... Content-Type: text/xml
... SOAPAction: /
...
... <?xml version="1.0"?>
... <SOAP-ENV:Envelope
...  SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
...  xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
...  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
...  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
...  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
...  <SOAP-ENV:Body>
...    <m:echoDate xmlns:m="http://www.soapware.org/">
...      <arg1 xsi:type="xsd:dateTime">1970-11-27T11:34:56.000Z</arg1>
...    </m:echoDate>
...  </SOAP-ENV:Body>
... </SOAP-ENV:Envelope>
... """ % (user_name, user_password))
HTTP/1.0 200 OK
Content-Length: ...
Content-Type: text/xml...
<BLANKLINE>
...1970-11-27T10:34:56...
>>> print http(r"""
... POST /test_folder_1_ HTTP/1.0
... Authorization: Basic %s:%s
... Content-Length: 102
... Content-Type: text/xml
... SOAPAction: /
...
... <?xml version="1.0"?>
... <SOAP-ENV:Envelope
...  SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
...  xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
...  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
...  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
...  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
...  <SOAP-ENV:Body>
...    <m:echoDecimal xmlns:m="http://www.soapware.org/">
...      <arg1 xsi:type="xsd:float">123456789.0123</arg1>
...    </m:echoDecimal>
...  </SOAP-ENV:Body>
... </SOAP-ENV:Envelope>
... """ % (user_name, user_password))
HTTP/1.0 200 OK
Content-Length: ...
Content-Type: text/xml...
<BLANKLINE>
...123456789.0123...
>>> print http(r"""
... POST /test_folder_1_ HTTP/1.0
... Authorization: Basic %s:%s
... Content-Length: 102
... Content-Type: text/xml
... SOAPAction: /
...
... <?xml version="1.0"?>
... <SOAP-ENV:Envelope
...  SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
...  xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
...  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
...  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
...  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
...  <SOAP-ENV:Body>
...    <m:echoBoolean xmlns:m="http://www.soapware.org/">
...      <arg1 xsi:type="xsd:boolean">1</arg1>
...    </m:echoBoolean>
...  </SOAP-ENV:Body>
... </SOAP-ENV:Envelope>
... """ % (user_name, user_password))
HTTP/1.0 200 OK
Content-Length: ...
Content-Type: text/xml...
<BLANKLINE>
...1...

错误

如果您需要引发错误,您可以通过常规方式引发异常,或者(如果您需要更多控制错误信息)直接返回一个ZSI.Fault对象。两种情况都会导致返回错误响应

>>> print http(r"""
... POST /test_folder_1_ HTTP/1.0
... Authorization: Basic %s:%s
... Content-Length: 104
... Content-Type: text/xml
... SOAPAction: /
...
... <?xml version="1.0"?>
... <SOAP-ENV:Envelope
...  SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
...  xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
...  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
...  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
...  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
...  <SOAP-ENV:Body>
...    <m:echoInteger xmlns:m="http://www.soapware.org/">
...      <arg1 xsi:type="xsd:int">hello</arg1>
...    </m:echoInteger>
...  </SOAP-ENV:Body>
... </SOAP-ENV:Envelope>
... """ % (user_name, user_password), handle_errors=True)
HTTP/1.0 500 Internal Server Error
Content-Length: ...
Content-Type: text/xml
<BLANKLINE>
<SOAP-ENV:Envelope xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ZSI="http://www.zolera.com/schemas/ZSI/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><SOAP-ENV:Header></SOAP-ENV:Header><SOAP-ENV:Body><SOAP-ENV:Fault><faultcode>SOAP-ENV:Server</faultcode><faultstring>Processing Failure</faultstring><detail><ZSI:FaultDetail><ZSI:string>
...

这是一个ZSI错误响应

>>> print http(r"""
... POST /test_folder_1_ HTTP/1.0
... Authorization: Basic %s:%s
... Content-Length: 104
... Content-Type: text/xml
... SOAPAction: /
...
... <?xml version="1.0"?>
... <SOAP-ENV:Envelope
...  SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
...  xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
...  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
...  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
...  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
...  <SOAP-ENV:Body>
...    <m:testFault xmlns:m="http://www.soapware.org/">
...    </m:testFault>
...  </SOAP-ENV:Body>
... </SOAP-ENV:Envelope>
... """ % (user_name, user_password), handle_errors=True)
HTTP/1.0 200 OK
Content-Length: 488
Content-Type: text/xml
<BLANKLINE>
<SOAP-ENV:Envelope xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ZSI="http://www.zolera.com/schemas/ZSI/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><SOAP-ENV:Header></SOAP-ENV:Header><SOAP-ENV:Body><SOAP-ENV:Fault><faultcode>SOAP-ENV:Client</faultcode><faultstring>Testing the zsi fault</faultstring></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>

复杂数据类型

为了使ZSI能够成功序列化复杂数值(类的实例),您必须定义一个描述对象的typecode(有关定义typecode的详细信息,请参阅ZSI文档)。一旦定义了typecode,它必须通过实例的属性名'typecode'可访问,以便自动序列化。

>>> print http(r"""
... POST /test_folder_1_ HTTP/1.0
... Authorization: Basic %s:%s
... Content-Length: 104
... Content-Type: text/xml
... SOAPAction: /
...
... <SOAP-ENV:Envelope
...  xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
...  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
...  xmlns:ZSI="http://www.zolera.com/schemas/ZSI/"
...  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
...  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
... <SOAP-ENV:Header></SOAP-ENV:Header>
... <SOAP-ENV:Body xmlns:ns1="urn:ws-xwebservices-com:XWebEmailValidation:EmailValidation:v2:Messages">
...   <ns1:ValidateEmailRequest>
...     <ns1:Email>jfroche@affinitic.be</ns1:Email>
...   </ns1:ValidateEmailRequest>
... </SOAP-ENV:Body>
... </SOAP-ENV:Envelope>""" % (user_name, user_password))
HTTP/1.0 200 OK
Content-Length: ...
Content-Type: text/xml
<BLANKLINE>
...jfroche@affinitic.be is OK...

内存测试

>>> import sys
>>> from xml.dom.minidom import Element, Node
>>> print sys.getrefcount(Element)
5
>>> from z3c.soap.tests.mailvalidation import ns1
>>> from ZSI import SoapWriter
>>> from ZSI import TC
>>> element = ns1.ValidateEmailRequest_Dec().pyclass()
>>> element._Email = 'foo@bar.be'
>>> sw = SoapWriter(nsdict={}, header=True, outputclass=None,
...                 encodingStyle=None)
>>> tc = TC.Any(aslist=1, pname='test')

我们序列化了之前创建的元素的多份副本

>>> res = sw.serialize([element, element, element, element, element], tc)
>>> print sys.getrefcount(Element)
19
>>> print sw
<SOAP-ENV:Envelope xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ZSI="http://www.zolera.com/schemas/ZSI/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><SOAP-ENV:Header></SOAP-ENV:Header><SOAP-ENV:Body><test xmlns:ns1="urn:ws-xwebservices-com:XWebEmailValidation:EmailValidation:v2:Messages" SOAP-ENC:arrayType="xsd:anyType[5]" xsi:type="SOAP-ENC:Array"><ns1:element><ns1:Email xsi:type="xsd:string">foo@bar.be</ns1:Email></ns1:element><ns1:element><ns1:Email xsi:type="xsd:string">foo@bar.be</ns1:Email></ns1:element><ns1:element><ns1:Email xsi:type="xsd:string">foo@bar.be</ns1:Email></ns1:element><ns1:element><ns1:Email xsi:type="xsd:string">foo@bar.be</ns1:Email></ns1:element><ns1:element><ns1:Email xsi:type="xsd:string">foo@bar.be</ns1:Email></ns1:element></test></SOAP-ENV:Body></SOAP-ENV:Envelope>
>>> print sys.getrefcount(Element)
19
>>> del res
>>> del sw.body.node
>>> del sw.body
>>> del sw.dom.node
>>> del sw.dom
>>> del sw
>>> print sys.getrefcount(Element)
19

因此,当删除soapwriter时,仍有19个Element引用仍然处于活动状态(这可能会与大型xml一起造成灾难)。

如果我们首先解除节点链接会怎样

>>> sw = SoapWriter(nsdict={}, header=True, outputclass=None,
...                 encodingStyle=None)
>>> res = sw.serialize([element, element, element, element, element], tc)
>>> print sys.getrefcount(Element)
19
>>> Node.unlink(sw.body.node)
>>> Node.unlink(sw.dom.node)
>>> print sys.getrefcount(Element)
8
>>> del res
>>> del sw.body.node
>>> del sw.body
>>> del sw.dom.node
>>> del sw.dom
>>> del sw
>>> print sys.getrefcount(Element)
6

因此,在删除soapwriter对象之前使用unlink时,Element的引用会更少。

变更日志

0.5.5 (2013-10-09)

  • 在从zope.app.publisher.browser.viewmeta导入_handle_for时不要失败,因为它已移动到zope.browserpage.metaconfigure

0.5.4 (2013-05-21)

  • 添加Zope 2.13支持

  • 删除collective.autopermission依赖关系

0.5.3 (2011-01-05)

  • 删除CMF依赖关系,使用collective.autopermission定义权限

  • 使用Python的doctest模块而不是已弃用的zope.testing.doctest

0.5.2 (2010-05-05)

  • 添加Zope 2.12支持(感谢E. Leddy的补丁)

0.5.1 (2009-12-07)

  • 将元文件包含到配置中

0.5 - (2009-09-22)

  • 修复并测试zsi soapwriter中的内存泄漏

  • buildout更新

0.4 - (2009-05-04)

  • 正确返回序列化字符串

0.3 - (2008-12-17)

  • 正确处理ZSI.Fault异常

0.2 - (2008-11-14)

  • 正确处理未经授权异常

  • 添加SOAP访问权限

  • 如果引发未经授权异常,则从响应中删除领域

0.1 - (2008-11-13)

  • 初始版本

项目详情


下载文件

下载适合您平台文件的文件。如果您不确定选择哪个,请了解更多关于安装包的信息。

源分布

z3c.soap-0.5.5.zip (47.0 kB 查看哈希值)

上传时间

支持