3

花了最后一天敲打我的头,并希望有任何帮助!

我正在构建一个使用第 3 方 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 还很陌生,目前我的运气并不好。

谢谢!

4

2 回答 2

1

目前 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);
});
于 2020-10-22T09:59:07.467 回答
-1

我确定了几件事:我在 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
}
于 2017-10-12T03:36:21.503 回答