Javascript is required
最佳实践发布于 2026-07-28审校于 2026-08-085 分钟阅读

JSON 转 XML 与 SOAP Web Service 桥接:Envelope、Body 和命名空间

SOAP 请求不是把 JSON 改成 XML 就结束了。客户端还要构造 Envelope 和 Body,绑定操作命名空间,按 SOAP 版本设置 HTTP 头,并按协议处理 Fault。本文展示一个 SOAP 1.1 的受控 Envelope 生成片段,不提供某个真实服务的 endpoint,也不把普通 XML 转换器当成 SOAP 客户端。

JSON to XMLSOAPEnvelopeNamespace

一、问题概述:业务 XML 与 SOAP 消息不是同一层

业务 payload 只描述操作参数;SOAP Envelope 负责协议外壳,Body 承载操作元素,namespace URI 决定元素所属词汇。缺少正确命名空间或把 payload 放在 Envelope 外,服务端可能返回 Fault,即使 XML 本身格式良好。

二、最小复现:Envelope 包住命名空间明确的操作

下面是抽象的 SOAP 1.1 形状,urn:example:catalog 只是示例命名空间,不代表真实服务。实际操作名、参数名和版本必须以服务 WSDL 或接口文档为准。

const body = "<GetPrice xmlns=\"urn:example:catalog\"><sku>book-1</sku></GetPrice>";
const envelope =
  "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:cat=\"urn:example:catalog\">" +
  "<soapenv:Body>" + body + "</soapenv:Body>" +
  "</soapenv:Envelope>";
console.log(envelope);

三、根因:namespace、版本和 HTTP 绑定必须同时正确

XML 前缀只是别名,namespace URI 才是语义标识;操作元素通常还需要使用服务定义的 URI。SOAP 1.1 与 SOAP 1.2 的 Envelope URI 和 Content-Type 不同,SOAPAction 也可能由服务契约要求。只生成 XML 字符串无法自动完成这些协议选择。

四、推荐方案:先读取 WSDL,再分层构造请求

把 JSON 校验、业务 payload、SOAP Envelope、HTTP headers 和 Fault 解析拆成独立层。先从 WSDL/接口文档确认版本、namespace、操作、参数顺序和必需头部,再调用经过验证的 SOAP 客户端或 HTTP 适配器;不要凭字段名猜协议。

五、完整代码:构造受控的 SOAP 1.1 Envelope

以下函数只包装已经生成并验证过的 payload XML,并拒绝嵌套 Envelope。它不发送网络请求、不伪造 endpoint,也不处理 WS-Security;这些内容必须由具体服务契约决定。

function escapeXml(value: string): string {
  return value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll("\"", "&quot;").replaceAll("'", "&apos;");
}

function buildSoap11Envelope(payloadXml: string, operationNamespace: string): string {
  if (/<(?:[A-Za-z_][A-Za-z0-9_.-]*:)?Envelope(?:\s|\/?>)/.test(payloadXml)) {
    throw new Error("payload must not contain a SOAP Envelope");
  }
  const ns = escapeXml(operationNamespace);
  return "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:op=\"" + ns + "\">" +
    "<soapenv:Body>" + payloadXml + "</soapenv:Body></soapenv:Envelope>";
}

console.log(buildSoap11Envelope("<op:GetPrice xmlns:op=\"urn:example:catalog\"><op:sku>book-1</op:sku></op:GetPrice>", "urn:example:catalog"));

六、常见错误方案

把普通 JSON→XML 输出直接 POST 到 SOAP endpoint 会缺少 Envelope、Body 或命名空间;把 prefix 名称当成 namespace URI 会在服务端匹配失败;只检查 HTTP 200 也会漏掉 SOAP Fault。另一个错误是把 SOAP 1.1 的头部和 SOAP 1.2 混用。

七、边界条件:Fault、版本和安全扩展

成功响应和 Fault 都是 SOAP XML,需要按 Envelope 版本解析并保留 faultcode、faultstring 或对应版本字段。WS-Addressing、WS-Security、签名、时钟偏差和附件传输不能由通用 XML 转换器自动补齐;是否需要它们要看服务契约。

八、如何验证桥接请求

先对 payload 和 Envelope 做 XML parser 解析,断言 Envelope URI、Body 层级、操作 namespace 和必需元素。再使用服务提供的 WSDL 样例或测试端点验证 HTTP Content-Type、SOAPAction、Fault 映射和响应 namespace;不要只比较字符串缩进。

九、FAQ

问:生成了合法 XML 就是 SOAP 客户端吗?答:不是,还要满足 SOAP 版本、Envelope、namespace、HTTP 绑定和 Fault 处理。

问:SOAP 1.1 和 1.2 可以共用 Envelope 吗?答:不能直接混用,URI、Content-Type 和部分头部规则不同。

问:能否从 JSON 字段名自动生成 WSDL 操作?答:不能,操作和类型必须来自服务契约。

十、总结

JSON→SOAP 桥接应分层处理:先根据 WSDL 生成业务 payload,再按 SOAP 版本包装 Envelope/Body 和 namespace,最后由 HTTP 适配器发送并解析 Fault。普通 XML 转换只解决表示层,不能代替完整 SOAP 客户端。

来源与延伸阅读

技术审校所依据的规范与权威参考资料。

相关文章

继续阅读

可打开关联的浏览器工具,使用自己的样本验证文中的处理流程。

打开关联工具