在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的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | bb4b8ebd04b4035e758af80bd6aced74d9e7db46e5955dad0762f8fafaa28489 |
|
MD5 | 104564d4c7ba242e0ab9e29bd7b04e85 |
|
BLAKE2b-256 | 1da3612ca10198b39046f8500ea811f4aa3f0ee063204512bca095f7aa7b0c1c |