最后一天我为此苦恼不已,非常感谢任何帮助!
我正在构建一个使用第三方 SOAP Web 服务的应用程序。这是基于node.js并使用node-soap。不幸的是,WSDL 文件有点损坏,我需要解决它。
这是我正在使用的代码:
var url = 'http://domainexample.com/ws/connectionService.cfc?wsdl';
var session = 'super secret string'
var args = { connectionID: session }
soap.createClient(url, function (err, client) {
client.connectionService_wrapService['connectionservice.cfc'].isConnected(args, function (err, result) {
console.log(result);
});
});
这是我得到的错误。大多数其他方法都可以正常工作:
org.xml.sax.SAXException:反序列化参数\'connectionID\':找不到类型{的反序列化器 http://www.w3.org/2001/XMLSchema}anyType'
这是该方法生成的消息:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:impl="http://rpc.xml.cfml/
ws/ConnectionService.cfc" xmlns:intf="http://rpc.xml.cfml/ws/ConnectionService.cfc">
<soap:Body>
<impl:isConnected>
<connectionID>super secret string</connectionID>
</impl:isConnected>
</soap:Body>
</soap:Envelope>
我发现 WSDL 文件没有为某些方法(例如这个方法)的 connectionID 参数定义正确的类型属性。它应该是 xsd:string,这就是我调用的有效方法的含义。
在尝试使用 SOAP UI 之后,我发现向 connectionID 部分添加了一个类型属性 (xsi:type=xsd:string),并添加了一个架构 (xmlns:xsd="http://www.w3.org/ 2001/XMLSchema")修复了它。这是我需要生成的 XML:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:impl="http://rpc.xml.cfml/
ws/ConnectionService.cfc" xmlns:intf="http://rpc.xml.cfml/ws/ConnectionService.cfc">
<soap:Body>
<impl:isConnected>
<connectionID xsi:type="xsd:string">auth-string-here</connectionID>
</impl:isConnected>
</soap:Body>
</soap:Envelope>
但我一生都无法弄清楚如何通过节点肥皂来做到这一点。我尝试使用属性键添加类型,但是它似乎仅在参数中有父节点和子节点时才起作用。
所以,如果我把这个传下去:
var args = {
test: {
connectionID:
{
attributes: {
'xsi:type': 'xsd:string'
},
$value: session
}
}
};
我得到以下信息:
<impl:isConnected>
<test>
<connectionID xsi:type="xsd:string">super secret string</connectionID>
</test>
</impl:isConnected>
但我只需要一个级别,就像这样:
var args = {
connectionID:
{
attributes: {
'xsi:type': 'xsd:string'
},
$value: session
}
};
所以我明白了:
<impl:isConnected>
<connectionID xsi:type="xsd:string">super secret string</connectionID>
</impl:isConnected>
但这似乎并没有发生。事实上,当我将其保留到单个节点时,它根本没有添加类型属性。我还需要找出一种在调用中添加额外模式的方法。我通过手动将其添加到肥皂节点核心代码中来解决这个问题,但这根本不干净(不过我可以接受它)。
有什么想法吗?我对 SOAP 还很陌生,目前运气不太好。
谢谢!
目前 Node-Soap 不允许在客户端选项中传递“attributesKey”值,并且默认情况下不使用该值。
我可以让它工作的唯一方法是定义我自己的 WSDL 对象(使用 open_wsdl(uri, options,callback) 函数),在第二个参数处传递选项(不包括“attributesKey”,因为它不会分配它)但是然后对生成的对象进行如下分配:
open_wsdl(wsdlUrl, setupSoapWsdlConfig() /* Here you can pass other params as valueKey and xmlKey but not attributesKey */, (err, wsdl: WSDL) => {
if ( err ) { reject(err); }
this.wsdl = wsdl;
wsdl.options.attributesKey = '$attributes'; // Specify attributesKey
resolve(wsdl);
});
要添加架构,您可以在访问客户端后执行此操作,如本答案所示:https://stackoverflow.com/a/78491541/2087214
这里是:
if (!client['wsdl'].xmlnsInEnvelope.includes('xmlns:xsd=')) {
client['wsdl'].xmlnsInEnvelope += ' xmlns:xsd="http://www.w3.org/2001/XMLSchema"';
}
那个
const args = {
connectionID:{
attributes: {
'xsi:type': 'xsd:string'
},
$value: session
}
}
应该可以工作,因为我现在也为我自己的功能完全这样做。不确定在过去几年中他们是否更新了客户端,以便现在可以使用?
我确定的几件事: 我在 wsdl 定义中包含以下命名空间:
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
此外,在响应中确保信封中有以下命名空间:
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
我也必须在以下位置手动修复节点肥皂库中的一些问题 lib/wsdl.js WSDL.prototype._xmlnsMap 函数以添加上述名称空间
我添加了以下代码来实现它:
WSDL.prototype._xmlnsMap = function() {
var xmlns = this.definitions.xmlns;
var str = '';
for (var alias in xmlns) {
if (alias === '' || alias === TNS_PREFIX) {
continue;
}
var ns = xmlns[alias];
switch (ns) {
case "http://www.w3.org/2001/XMLSchema-instance" : //xsi support
case "http://www.w3.org/2001/XMLSchema" : //xsd support
str += ' xmlns:' + alias + '="' + ns + '"';
continue;
case "http://xml.apache.org/xml-soap" : // apachesoap
case "http://schemas.xmlsoap.org/wsdl/" : // wsdl
case "http://schemas.xmlsoap.org/wsdl/soap/" : // wsdlsoap
case "http://schemas.xmlsoap.org/wsdl/soap12/": // wsdlsoap12
case "http://schemas.xmlsoap.org/soap/encoding/" : // soapenc
continue;
}
if (~ns.indexOf('http://schemas.xmlsoap.org/')) {
continue;
}
if (~ns.indexOf('http://www.w3.org/')) {
continue;
}
if (~ns.indexOf('http://xml.apache.org/')) {
continue;
}
str += ' xmlns:' + alias + '="' + ns + '"';
}
return str;
};
更新回复:
<soap:Body><IsAliveResponse><return xsi:type="xsd:string">success</return>
</IsAliveResponse></soap:Body>
这是我在服务文件中使用的:
return:{
attributes: {
'xsi:type': 'xsd:string'
},
$value: healthCheck
}