Magento Soap API V2响应内容长度不正确

时间:2012-10-09 03:49:15

标签: api magento soap magento-1.7

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

我一直在聆听我的声音,因为每当我在PHP中制作任何东西时,API工作正常。此外,库存更新工作正常,但检索订单/发票信息却没有(实际上偶尔会有1%的时间检索)

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

所以我的推论是因为SOAP API(我使用的是版本2)不正确

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

soapUI输出以下错误:

错误:发生错误[Content-Length分隔邮件正文的过早结束(预期:267;已收到:266),有关详细信息,请参阅错误日志

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

任何人都可以告诉我为什么会出现这个错误以及如何修复它?

3 个答案:

答案 0 :(得分:3)

我将假设您正在使用符合WS-I的SOAP API v2,因为我有完全相同的问题;如果没有,那么这仍然可能适用。如果没有符合WS-I标准,我就无法连接到v2 API,这就是我发现这个错误的方法。

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

在SOAP响应中,有一些字符串替换正在进行,用<soap:operation soapAction=""></soap:operation>代替<soap:operation soapAction="" />,依此类推。这显然会导致内容长度计算出现问题 - 这也发生在WSDL定义响应中,但它似乎没有引起问题。

通过使用下面的代码替换try花括号之间的代码,我能够成功连接到SOAP API。基本上,我最后清除标题并重新计算内容长度 AFTER 更换字符串:

            $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);

希望这有帮助

答案 1 :(得分: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);

答案 2 :(得分:0)

对我有用的唯一解决方案是将API端点切换为NOT使用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网址

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;
}

Apache .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