12.4. 调试 SOAP Web 服务

SOAP 库提供了一种简单的方法来查看幕后发生的事情。

开启调试只需在 SOAPProxy 的配置中设置两个标志即可。

示例 12.7. 调试 SOAP Web 服务

>>> from SOAPpy import SOAPProxy
>>> url = 'http://services.xmethods.net:80/soap/servlet/rpcrouter'
>>> n = 'urn:xmethods-Temperature'
>>> server = SOAPProxy(url, namespace=n)     1
>>> server.config.dumpSOAPOut = 1            2
>>> server.config.dumpSOAPIn = 1
>>> temperature = server.getTemp('27502')    3
*** Outgoing SOAP ******************************************************
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
  xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
  xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:xsd="http://www.w3.org/1999/XMLSchema">
<SOAP-ENV:Body>
<ns1:getTemp xmlns:ns1="urn:xmethods-Temperature" SOAP-ENC:root="1">
<v1 xsi:type="xsd:string">27502</v1>
</ns1:getTemp>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
************************************************************************
*** Incoming SOAP ******************************************************
<?xml version='1.0' encoding='UTF-8'?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<SOAP-ENV:Body>
<ns1:getTempResponse xmlns:ns1="urn:xmethods-Temperature"
  SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<return xsi:type="xsd:float">80.0</return>
</ns1:getTempResponse>

</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
************************************************************************

>>> temperature
80.0
1 首先,像往常一样使用服务 URL 和命名空间创建 SOAPProxy
2 其次,通过设置 server.config.dumpSOAPInserver.config.dumpSOAPOut 来开启调试。
3 第三,像往常一样调用远程 SOAP 方法。SOAP 库将打印出传出的 XML 请求文档和传入的 XML 响应文档。这就是 SOAPProxy 为您所做的所有艰苦工作。是不是很吓人?让我们来分解一下。

发送到服务器的大多数 XML 请求文档只是样板文件。忽略所有命名空间声明;对于所有 SOAP 调用,它们都将相同(或相似)。“函数调用”的核心是 <Body> 元素中的这一片段

<ns1:getTemp                                 1
  xmlns:ns1="urn:xmethods-Temperature"       2
  SOAP-ENC:root="1">
<v1 xsi:type="xsd:string">27502</v1>         3
</ns1:getTemp>
1 元素名称是函数名称,getTempSOAPProxy 使用 getattr 作为调度程序。它不是根据方法名称调用单独的本地方法,而是实际使用方法名称来构造 XML 请求文档。
2 函数的 XML 元素包含在特定的命名空间中,该命名空间是您在创建 SOAPProxy 对象时指定的命名空间。不要担心 SOAP-ENC:root;那也是样板文件。
3 函数的参数也被转换为 XML。 SOAPProxy 会内省每个参数以确定其数据类型(在本例中,它是一个字符串)。参数数据类型进入 xsi:type 属性,后跟实际的字符串值。

XML 返回文档同样易于理解,一旦您知道要忽略什么。关注 <Body> 中的这一片段

<ns1:getTempResponse                             1
  xmlns:ns1="urn:xmethods-Temperature"           2
  SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<return xsi:type="xsd:float">80.0</return>       3
</ns1:getTempResponse>
1 服务器将函数返回值包装在 <getTempResponse> 元素中。按照惯例,此包装器元素是函数的名称,加上 Response。但它实际上可以是任何东西;SOAPProxy 注意到的重要事情不是元素名称,而是命名空间。
2 服务器在我们请求中使用的命名空间中返回响应,该命名空间与我们最初创建 SOAPProxy 时指定的命名空间相同。在本章的后面,我们将看到如果您在创建 SOAPProxy 时忘记指定命名空间会发生什么。
3 指定了返回值及其数据类型(它是一个浮点数)。 SOAPProxy 使用此显式数据类型来创建具有正确本机数据类型的 Python 对象并返回它。