【问题标题】:Can't formulate the response object for SOAP Node.js无法为 SOAP Node.js 制定响应对象
【发布时间】:2013-12-21 03:21:42
【问题描述】:

我正在使用 node-soap 编写一个 SOAP Node.js 网络服务,但我不知道如何正确地制定响应。

我正在使用Web Connector 将 web 应用程序与 QuickBooks 2013 集成。客户端将请求进行身份验证,我可以记录传递的参数,因此我知道它正在被调用,但我无法得到正确的响应。

文档说它期望一个字符串数组作为响应。 WSDL 的相关部分如下所示:

  <s:element name="authenticateResponse">
    <s:complexType>
      <s:sequence>
        <s:element minOccurs="0" maxOccurs="1" name="authenticateResult" type="tns:ArrayOfString" />
      </s:sequence>
    </s:complexType>
  </s:element>

  <s:complexType name="ArrayOfString">
    <s:sequence>
      <s:element minOccurs="0" maxOccurs="unbounded" name="string" nillable="true" type="s:string" />
    </s:sequence>
  </s:complexType>

 <wsdl:message name="authenticateSoapOut">
    <wsdl:part name="parameters" element="tns:authenticateResponse" />
</wsdl:message>

<wsdl:operation name="authenticate">
  <wsdl:input message="tns:authenticateSoapIn" />
  <wsdl:output message="tns:authenticateSoapOut" />
</wsdl:operation>

 <wsdl:operation name="authenticate">
  <soap:operation soapAction="http://developer.intuit.com/authenticate" style="document" />
  <wsdl:input>
    <soap:body use="literal" />
  </wsdl:input>
  <wsdl:output>
    <soap:body use="literal" />
  </wsdl:output>
</wsdl:operation>

我尝试了许多不同的方法来配置响应对象,但不断收到来自客户端的错误(QuickBooks Web 连接器)

我的 JavaScript 是:

    var myService = {
          'QBWebConnectorSvc': {
              'QBWebConnectorSvcSoap': {
                  authenticate: function(args) {

                           //i have tried many variations of nesting arrays/objects etc.
                    var toReturn = {
                        "ArrayOfString":[guid()," "," "," "]
                    };
                    return toReturn;
                  }
              }
          }
      }

     var xml = require('fs').readFileSync('qbwc.wsdl', 'utf8'),
          server = http.createServer(function(request,response) {
              response.end("404: Not Found: "+request.url)
          });

    server.listen(8000);

    soap.listen(server, '/wsdl', myService, xml);

不知何故,我需要构建“ArrayOfString”,但我不知道该怎么做;我对整个肥皂行业都不熟悉。

【问题讨论】:

  • 你遇到了什么错误?
  • @JohnB 我实际上不记得了,我决定使用 keithpalmers php 框架,只是制作我从节点调用的提交端点,两个应用程序都与同一个数据库通信。
  • 回想起来它永远不会验证
  • 您可能不再感兴趣,但对于其他偶然发现此问题的人:QBWC 不喜欢 node-soap 为数组创建的 XML 响应。我已经通过劫持动态创建的响应而不是硬编码它should be 来确认这一点。我正在努力更好地理解 node-soap 如何创建 XML,以便我可以修改它以发送 QBWC 所期望的内容。当我得到它的工作时,我肯定会在这里发布一个答案。
  • 上周我刚刚与node-soap 的命名空间策略搏斗,我完全从头开始重新编写了WSDL 解析器来处理它。但是我不是在编写服务器,我不知道这是否与您遇到的问题相同,但似乎很可能。 node-soap 将对象文字转换为 XML 的方式相当简单,但命名空间不是。

标签: javascript node.js soap wsdl quickbooks


【解决方案1】:

简答:

您的身份验证函数应如下所示:

authenticate: function(args) {
    return {
        authenticateResult: { string: [guid(), {}] }
    };
}

解释:

您的代码有几处错误,我将发布每个错误消息,以便将来遇到相同问题的任何人更容易搜索它们。

QBWC1012:对象引用未设置为对象的实例。

您应该在对象中返回authenticateResult,而不是ArrayOfString

QBWC1012:由于以下错误消息,身份验证失败。索引超出了数组的范围。

QBWC 不喜欢 node-soap 为数组创建的 XML 响应。如果您在对象中返回一个数组(即return { authenticateResult: [guid(), ""] }:

<tns:authenticateResponse xmlns:tns="http://developer.intuit.com/" xmlns="http://developer.intuit.com/">
    <tns:authenticateResult>bdaa63cf-2d26-4d6b-8a54-6f519af6e8d4</tns:authenticateResult>
</tns:authenticateResponse>

这就是 QBWC 所期待的:

<tns:authenticateResponse xmlns:tns="http://developer.intuit.com/" xmlns="http://developer.intuit.com/">
    <tns:authenticateResult>
        <tns:string>bdaa63cf-2d26-4d6b-8a54-6f519af6e8d4</tns:string>
        <tns:string></tns:string>
    </tns:authenticateResult>
</tns:authenticateResponse>

第一个问题是命名空间错误。第二个是 node-soap 跳过空字符串并且不将其包含在响应中,但 QBWC 正在寻找它(因此索引超出范围)。我发布的 hack-ish 解决方案将解决这两个问题:

  • authenticateResult 对象中添加一个以string 作为其键的数组将更正命名空间
  • node-soap 的objectToXML 解析器不会忽略空对象而不是空字符串。

【讨论】:

  • 这个答案让我省了几个小时的挫败感,谢谢!期待很快获得丰厚的回报。 :-)
  • 享受您的声誉,您应得的! :-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多