3

我们正在尝试将我们的 magento 安装与第三方库存管理应用程序(建立在 .net 上)连接起来。但是同步不起作用,第三方告诉我soap api正在返回一个空响应。

我一直在倾听,因为每当我在 PHP 中做任何事情时,API 都可以正常工作。此外库存更新工作正常,但检索订单/发票信息不能(实际上它偶尔会在 1% 的时间里)

由于间歇性的性质,我们认为这一定是网络问题,但经过大量搜索并将 mage::log() 添加到核心 api 文件中,我可以看到连接正在发生,并且响应对象正在创建更多Magento。

所以我的推论是 SOAP API 有问题(我使用的是版本 2)

我已经安装了soapUI并设置了我们的集成,它正确地接收来自WSDL文件的方法,但是当我尝试访问“登录”方法时,我得到一个空响应,即使我输入了不正确的登录详细信息,它也是空的。

soapUI 输出以下错误:

ERROR: 发生错误 [Premature end of Content-Length delimited message body (expected: 267; received: 266],详见错误日志

因此,似乎 http 标头存在问题,某些函数能够返回响应(当然,如果没有登录哈希,它只是无效的,但至少它是一个响应)。从我对 java 和 .net 的(非常有限的)理解来看,它们在这些方面比 php 更严格,这表明为什么 php 集成没有问题。

谁能告诉我为什么会发生这个错误以及如何解决它?

4

3 回答 3

3

我假设您使用的是符合 WS-I 的 SOAP API v2,因为我遇到了同样的问题;如果不是,那么这仍然可能适用。如果不符合 WS-I,我永远无法连接到 v2 API,这就是我发现这个 bug 的原因。

如果您查看该app/code/core/Mage/Api/Model/Server/Wsi/Adapter/Soap.php文件,您将在公共运行函数中看到该文件基本上分为两部分 - 1 用于 WSDL 定义响应,1 用于实际 SOAP 响应。

在 SOAP 响应中有一些字符串替换、替换<soap:operation soapAction=""></soap:operation>等等<soap:operation soapAction="" />。这显然会导致内容长度计算出现问题 - 这也发生在 WSDL 定义响应中,但似乎不会导致问题。

通过将 try 大括号之间的代码替换为下面的代码,我能够成功连接到 SOAP API。基本上,在字符串替换发生,我最终清除了标题并重新计算了内容长度:

            $this->_instantiateServer();

            $content = preg_replace(
                        '/(\>\<)/i',
                        ">\n<",
                        str_replace(
                                '<soap:operation soapAction=""></soap:operation>',
                                "<soap:operation soapAction=\"\" />\n",
                                str_replace(
                                        '<soap:body use="literal"></soap:body>',
                                        "<soap:body use=\"literal\" />\n",
                                        preg_replace(
                                            '/<\?xml version="([^\"]+)"([^\>]+)>/i',
                                            '<?xml version="$1" encoding="'.$apiConfigCharset.'"?>',
                                            $this->_soap->handle()
                                        )
                                )
                        )
                    );

            $this->getController()->getResponse()
                      ->clearHeaders()
                      ->setHeader('Content-Type','text/xml; charset='.$apiConfigCharset)
                      ->setHeader('Content-Length',strlen($content))
                      ->setBody($content);

希望这可以帮助

于 2012-10-09T04:26:29.310 回答
2

作为参考,如果您使用的是 V2 版本,则需要更改:

/app/core/Mage/Api/Model/Server/V2/Adapter/Soap.php

关于第 62 行的内容替换为try{}

$this->_instantiateServer();
$content = preg_replace(
    '/<\?xml version="([^\"]+)"([^\>]+)>/i',
    '<?xml version="$1" encoding="'.$apiConfigCharset.'"?>',
    $this->_soap->handle()
);
$this->getController()->getResponse()
    ->clearHeaders()
    ->setHeader('Content-Type','text/xml; charset='.$apiConfigCharset)
    ->setHeader('Content-Length',strlen($content))
    ->setBody($content);

这并没有为我解决所有问题,有一些神秘的空白将所有事情都搞砸了,一个是结束标签后的空格,另一个是客户在他们的电话号码末尾添加了两个空格(?? )

无论如何,为了清除这两个我做了......

这并没有为我解决所有问题,仍然存在一些空白问题,我添加了一些额外的 preg_replace 以快速修复它

$content = preg_replace('/\s+/', ' ', $content);
$content = preg_replace('/Envelope> /', 'Envelope>', $content);
于 2012-10-11T01:31:14.953 回答
0

对我有用的唯一解决方案是将 API 端点切换为不使用 index.php

变化来自: domain.com/index.php/api/v2_soap/index/wsdl/1

到: domain.com/api/v2_soap/?wsdl=1

注意从 url 中删除了 index.php。这样,请求将通过 api.php 入口点而不是 index.php。作为一个副作用,api 开始工作得更快,因为 api.php 更轻量级。

采取的步骤:

  • 确保您在 nginx 或 .htaccess 中设置了正确的重定向规则(见下文)
  • 清除 Magento 缓存
  • 在浏览器中打开 WSDL (domain.com/api/v2_soap/?wsdl=1) 并验证它是否正确。soap:address 节点不应包含 index.php 部分:

    <soap:address location="http://domain.com/api.php/?type=v2_soap"/>

  • 在您的客户端脚本中使用 domain.com/api/v2_soap/?wsdl=1 url

Nginx 配置:

location /api {
    rewrite ^/api/rest /api.php?type=rest last;
    rewrite ^/api/v2_soap /api.php?type=v2_soap last;
    rewrite ^/api/soap /api.php?type=soap last;
}

阿帕奇.htaccess:

取消注释行:

RewriteRule ^api/([a-z][0-9a-z_]+)/?$ api.php?type=$1 [QSA,L]

其他对我不起作用的解决方案:

  • 编辑 V2/Adapter/Soap.php
  • 编辑 Wsi/Adapter/Soap.php

我正在开发 Magento 1.9.2.4

于 2016-03-24T13:00:51.927 回答