当wsdl消息具有相同的部件名称时,SoapServer映射功能不正确 [英] SoapServer maps functions incorectly when the wsdl messages have the same part name

查看:90
本文介绍了当wsdl消息具有相同的部件名称时,SoapServer映射功能不正确的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不确定这是php错误(错误的实现)还是我的错误(错误的理解SOAP协议/SoapServer,因为这是我第一次使用SoapServer)

I'm not sure if this is php bug (bad implementation) or my bug (bad understanding of the SOAP protocol / SoapServer as this is the first time I'm using SoapServer)

我注意到,如果有两个或多个具有相同wsdl:part的操作(即使wsdl:message,operation和soapAction是不同的),则SoapServer始终会调用第一个函数.在此示例中,我有两个函数multiply2multiply4都具有num(int)作为输入参数.今天早些时候,如果我更改部件名称(service1.wsdl),功能将正确映射.

I've noticed that if there are two or more operations with the same wsdl:part (even if the wsdl:message , operation and soapAction are different), The SoapServer will allways call the first function. In this example, I've two functions multiply2 and multiply4 both having num (int) as input parameter. earlier today, If I change the part name (service1.wsdl) the functions are mapped correctly.

尽管,我不介意使用不同的名称,在我看来,这就像一个错误.我是否缺少某些东西?还是应该打开一个错误?

Although, I don't mind using different names it looks to me like a bug. Am I missing something or should I open a bug ?

这是我创建的简单示例:

This is simple example I've crated:

非常简单的php类

<?php
class Multi
{
    function multiply2($num) { return ($num * 2 ); }
    function multiply4($num){ return ($num * 4 );  }
}
?>

对SoapServer进行了稍微更改(添加了日志记录-已改编来自这篇文章),但是当我也使用普通的SoapServer时,也会出现此问题:

And slightly changed SoapServer (with added logging - adapted from this post) but the issue appears when I'm using the plain SoapServer as well:

$server = new overloadedSoapServer("service.wsdl", array('soap_version' => SOAP_1_2,'encoding' => SOAP_ENCODED));
$server->setClass("multi");

if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $server->handle();
} 

这是客户端代码:

ini_set("soap.wsdl_cache_enabled", "0");
$client = new SoapClient('service.wsdl');
$client1 = new SoapClient('service1.wsdl');
echo "<pre>\nFrom service.wsdl:";
echo  "\n".$client->multiply2(10);
echo  "\n".$client->multiply4(10);
echo "</pre>";
echo "<pre>\nFrom service1.wsdl:";
echo  "\n".$client1->multiply2(10);
echo  "\n".$client1->multiply4(10);
echo "</pre>";

service.wsdlservice1.wsdl基本上是同一文件,但有两个例外:

service.wsdl and service1.wsdl are basically the same file, with two exception:

  1. 它们的端点不同(service.wsdl指向http://tests.simsimy.info/web/service.phpservice1.php指向http://tests.simsimy.info/web/service1.php,每个端点使用适当的wsdl加载SoapServer)
  2. service.wsdl multiply2Requestmultiply4Request中的
  3. 具有部分名称-num,而在service1.wsdl中的名称是不同的(num2num4)
  1. their endpoint are different (service.wsdl points to http://tests.simsimy.info/web/service.php and service1.php to http://tests.simsimy.info/web/service1.php each endpoint uses the appropriate wsdl to load the SoapServer)
  2. in service.wsdl multiply2Request and multiply4Request have the as part name - num, while in service1.wsdl the names are different (num2 and num4)

这是service.wsdl的完整wsdl

This is the full wsdl of service.wsdl

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
    xmlns:tns="http://tests.simsimy.info/web/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="service"
    targetNamespace="http://tests.simsimy.info/web/">
    <wsdl:message name="multiply2Request">
        <wsdl:part name="num" type="xsd:int"></wsdl:part>
    </wsdl:message>
    <wsdl:message name="multiply2Response">
        <wsdl:part name="res" type="xsd:int"></wsdl:part>
    </wsdl:message>

    <wsdl:message name="multiply4Request">
        <wsdl:part name="num" type="xsd:int"></wsdl:part>
    </wsdl:message>
    <wsdl:message name="multiply4Response">
        <wsdl:part name="res" type="xsd:int"></wsdl:part>
    </wsdl:message>
    <wsdl:portType name="dd">
        <wsdl:operation name="multiply2">
            <wsdl:input message="tns:multiply2Request"></wsdl:input>
            <wsdl:output message="tns:multiply2Response"></wsdl:output>
        </wsdl:operation>
        <wsdl:operation name="multiply4">
            <wsdl:input message="tns:multiply4Request"></wsdl:input>
            <wsdl:output message="tns:multiply4Response"></wsdl:output>
        </wsdl:operation>
    </wsdl:portType>
    <wsdl:binding name="serviceSOAP" type="tns:dd">
        <soap:binding style="document"
            transport="http://schemas.xmlsoap.org/soap/http" />
        <wsdl:operation name="multiply2">
            <soap:operation soapAction="http://tests.simsimy.info/web/multiply2" />
            <wsdl:input>
                <soap:body use="literal" />
            </wsdl:input>
            <wsdl:output>
                <soap:body use="literal" />
            </wsdl:output>
        </wsdl:operation>
        <wsdl:operation name="multiply4">
            <soap:operation soapAction="http://tests.simsimy.info/web/multiply4" />
            <wsdl:input>
                <soap:body use="literal" />
            </wsdl:input>
            <wsdl:output>
                <soap:body use="literal" />
            </wsdl:output>
        </wsdl:operation>
    </wsdl:binding>
    <wsdl:service name="multiply_service">
        <wsdl:port binding="tns:serviceSOAP" name="serviceSOAP">
            <soap:address location="http://tests.simsimy.info/web/service.php" />
        </wsdl:port>
    </wsdl:service>
</wsdl:definitions>

service1.wsdl中更改的部分:

<wsdl:message name="multiply2Request">
        <wsdl:part name="num2" type="xsd:int"></wsdl:part>
    </wsdl:message>
    <wsdl:message name="multiply2Response">
        <wsdl:part name="res" type="xsd:int"></wsdl:part>
    </wsdl:message>

    <wsdl:message name="multiply4Request">
        <wsdl:part name="num4" type="xsd:int"></wsdl:part>
    </wsdl:message>
    <wsdl:message name="multiply4Response">
        <wsdl:part name="res" type="xsd:int"></wsdl:part>
    </wsdl:message>

运行客户端代码时,我得到以下输出:

When I run the client code I get the following ouput:

From service.wsdl:
20
20

From service1.wsdl:
20
40

推荐答案

您可以将wsdl中的绑定样式从文档"更改为"rpc".

You can change the binding style in your wsdl from 'document' to 'rpc'.

首先,我认为这是一个缓存问题,因为您上面发布的服务器代码不包含用于禁用缓存的ini_set().但这不是缓存问题.

First I thought it is a cache problem as your posted server code above does not contains the ini_set() to disabled the cache. But is isn't a cache problem.

已跟踪http流量.客户端似乎工作不正常,这是SoapServer问题. (就像您提到的那样)..进一步调查...

Having traced http traffic. Client seems working porperly it is a SoapServer problem. (Like you mentioned).. Further investigating ...

已经提交了错误报告 -尽管目前尚不清楚这是一个错误.

A bug report has already been filed - although it is currently unclear if it is a bug.

错误报告中也提到了解决方法.如果可以,可以将绑定样式更改为rpc:

Workarounds are mentioned in the bug report too. You can change the binding style to rpc if this is ok for you:

更改

<soap:binding style="document"

<soap:binding style="rpc"

此替代方法对我有效.您会在此处找到有关绑定样式如何工作的非常有趣的文章.这可以帮助您确定rpc绑定样式是否适合您.

This workaround works for me. You will find a very interesting article on how binding styles work here. This may help you to decide whether rpc binding style is ok for you or not.

这篇关于当wsdl消息具有相同的部件名称时,SoapServer映射功能不正确的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆