Magento - 在Lion下使用MAMP堆栈时,SOAP API响应不完整

ste*_*ope 1 soap soapui magento

我使用soapUI测试了Magento的SOAP API.我成功登录并获得了登录哈希.然后我尝试检索产品列表,这很好.

这是在使用最新版本的Apache,mySQL和PHP的Linux服务器上.

然后我创建了Magento和数据库的备份.我想使用MAMP堆栈在Lion服务器上创建测试环境.Magento备份似乎工作正常,但SOAP API没有.

我再次使用soapUI获取登录哈希并尝试检索所有产品.但现在回应似乎不完整:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:Magento">
<SOAP-ENV:Body>
<ns1:catalogProductListResponseParam>
<result>
<complexObjectArray>
<product_id>7167</product_id>
<sku>000140</sku>
... etc ...
<complexObjectArray>34</complexObjectArray>
</category_ids>
<website_ids>
<complexObjectArray>1</complexObjectArray>
</website_ids>
</complexObjectArray>
<complexObjectArray>
<product
Run Code Online (Sandbox Code Playgroud)

为什么Lion/MAMP下的反应不完整?

Mat*_*eis 11

我曾经遇到过不完整的SOAP XML响应问题.

设置是这样的:

  • Linux服务器
  • Magento CE 1.5.1.0
  • 启用了WS-I遵从性的SOAP v2的使用
  • 调用sales_order.info

即使您使用不同的Magento版本和不同的SOAP调用,您也可能遇到与我类似的错误.问题是HTTP Content-Length标头计算错误,响应> 8000字节.

如何验证您是否受此错误的影响:

  1. 执行一个提供短响应的调用(例如,"catalog_category.info"只有一个商店视图,只有少数属性).如果XML已完成,请检查响应是否长度<= 8000字节.
  2. 将文件app/code/core/Mage/Api/Model/Server/Wsi/Adapter/Soap.php复制到您的app/code/local文件夹并编辑run()方法.如果在SOAP URL中使用"wsdl"参数,请编辑"if"结构的第一部分,否则编辑"else"部分.

第二种方式是更准确的方法,我会继续这样做.

  1. 打开文件并搜索 - > setBody()方法调用.如你所见,有一些搜索/替换魔法正在进行中.
  2. 将搜索/替换操作的结果写入变量并记录以供进一步检查.代码可能如下所示:

    public function run()
    {
        $apiConfigCharset = Mage::getStoreConfig("api/config/charset");
    
        if ($this->getController()->getRequest()->getParam('wsdl') !== null) {
            /* don't modify the first part ... */
        } else {
            try {
                $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()
                                        )
                                )
                        )
                );
                Mage::log($content, null, 'soap.log');
                $this->getController()->getResponse()
                     ->clearHeaders()
                     ->setHeader('Content-Type','text/xml; charset='.$apiConfigCharset)
                     ->setBody($content);
            } catch( Zend_Soap_Server_Exception $e ) {
                $this->fault( $e->getCode(), $e->getMessage() );
            } catch( Exception $e ) {
                $this->fault( $e->getCode(), $e->getMessage() );
            }
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 执行SOAP API调用并在Magento目录中打开var/log/soap.log.如果XML在日志文件中完成但在响应中没有,那么Content-Length标头就是问题所在.

如何更正Content-Length标头

  1. 保留Mage_Api_Model_Server_Wsi_Adapter_Soap的副本,并在我们刚修改的代码中添加一行:

    public function run()
    {
        $apiConfigCharset = Mage::getStoreConfig("api/config/charset");
    
        if ($this->getController()->getRequest()->getParam('wsdl') !== null) {
            /* don't modify the first part ... */
        } else {
            try {
                $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()
                                        )
                                )
                        )
                );
                Mage::log($content, null, 'soap.log');
                $this->getController()->getResponse()
                     ->clearHeaders()
                     ->setHeader('Content-Type','text/xml; charset='.$apiConfigCharset)
                     ->setHeader('Content-Length',strlen($content), true)
                     ->setBody($content);
            } catch( Zend_Soap_Server_Exception $e ) {
                $this->fault( $e->getCode(), $e->getMessage() );
            } catch( Exception $e ) {
                $this->fault( $e->getCode(), $e->getMessage() );
            }
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

    注意这一行:

    ->setHeader('Content-Length',strlen($content), true)
    
    Run Code Online (Sandbox Code Playgroud)

    我们计算并设置Content-Length标头.第三个参数true很重要,因为它告诉框架覆盖现有的Content-Length标头.

  2. 如果这样做,请删除Mage :: log()调用并重写代码以在您自己的扩展中使用.

如果你问为什么会出现这个问题,我无法准确地告诉你,因为我没有一直追捕这个bug.

从我所看到的,只要XML响应的长度<= 8000字节,一切都很好.如果响应超过8000个字节且XML由x行组成,则响应将被x个字符截断.看起来它是不同的回车代码和/或编码问题导致错误计算响应内容长度的问题.