Провел последний день, ударив головой в это, и был бы признателен за любую помощь!
Я создаю приложение, которое использует сторонний веб-сервис SOAP. Это основано на node.js и использует узел-мыло. К сожалению, файл 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 я обнаружил добавление атрибута type (xsi: type = xsd: string) к части connectionID и добавление схемы (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, и сейчас мне не очень повезло.
Благодарю!
Пара вещей, которые я убедился: я включил следующее пространство имен в мое определение 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
}