soap请求必须严格遵循wsdl契约,包括命名空间、元素顺序、空值表示等;推荐用zeep或jax-ws生成客户端代码,调试需抓取原始http流量逐字比对。
SOAP请求体必须严格匹配WSDL定义的soap:Body结构
WSDL文件里的message和portType决定了XML请求的根元素名、命名空间和子元素顺序。手写请求时,哪怕xmlns少一个冒号、xs:element声明的minOccurs="0"字段被意外包含,服务端都可能直接返回SOAP-ENV:Client错误。
- 用
wsdl2py(Zeep)或wsimport(JAX-WS)生成客户端代码,比手动拼XML更可靠 - 检查WSDL中
<binding></binding>下的style="document"还是style="rpc":前者要求soap:Body内直接是操作名元素,后者会多一层封装 - 命名空间前缀(如
tns:、ns1:)必须与WSDL中<definitions xmlns:...></definitions>声明一致,不能仅靠默认命名空间“省略”
响应XML解析失败常因命名空间或类型映射不一致
服务端返回的soap:Body里,元素可能带xmlns=""清空默认命名空间,或用xsi:type指定具体类型(如xsi:type="xsd:string"),而客户端解析器若忽略这些,就会把值读成None或报ElementTree.ParseError。
- Python用
lxml.etree时,显式传入namespaces参数,例如root.find('.//{http://example.com}Result', ns) - Java Axis2默认不校验
xsi:type,但启用schemaValidation=true后会因类型不匹配抛AxisFault - 响应中
SOAP-ENV:Fault的faultcode值(如Server或Client)比HTTP状态码更能定位问题根源
Zeep Python库自动处理命名空间但需注意strict=False的副作用
Zeep默认开启严格模式(strict=True),遇到WSDL未声明的字段或额外属性就报TypeError;设为False虽能跳过校验,但可能导致result对象缺失关键字段——尤其当服务端返回了可选元素却没在WSDL中标记minOccurs="0"时。