JSON 转 XML 与 SOAP Web Service 桥接:Envelope、Body 和命名空间
SOAP 请求不是把 JSON 改成 XML 就结束了。客户端还要构造 Envelope 和 Body,绑定操作命名空间,按 SOAP 版本设置 HTTP 头,并按协议处理 Fault。本文展示一个 SOAP 1.1 的受控 Envelope 生成片段,不提供某个真实服务的 endpoint,也不把普通 XML 转换器当成 SOAP 客户端。
一、问题概述:业务 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("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll("\"", """).replaceAll("'", "'");
}
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 客户端。
来源与延伸阅读
技术审校所依据的规范与权威参考资料。
相关文章
JSON 转 XML 遇到数组、重复同名元素与属性层级冲突的解决方案
在 JSON 转 XML 前定义数组、属性、文本和重复同名元素规则,附带有明确输入输出契约的订单转换示例。
实现原理JSON 转 XML:属性与 CDATA 的映射约定
说明 JSON 不原生区分 XML 属性、文本和 CDATA,建立显式字段约定并处理 XML 转义与 CDATA 中的 ]]> 边界。
最佳实践JSON HTTP 传输:Gzip、Brotli 与流式响应的选择
区分 JSON 压缩、转义和 HTTP Content-Encoding,说明 Gzip、Brotli、分页与 NDJSON 的适用边界,并给出可验证的浏览器流式读取示例。
继续阅读
可打开关联的浏览器工具,使用自己的样本验证文中的处理流程。
打开关联工具