php调用java发布的webservice
java 使用 spring webservice 发布的 service,由php使用SoapClient调用。
遇到有一个奇怪的现象,java调用发布的webservice,没有问题,使用工具SOAP UI调用,没有问题,
同样的php代码调用google的天气服务没问题,调用我们的wsdl就不行。
经过摸索调试,发现如下问题,以及解决的过程。
?
首先发布的wsdl如下:
?
?
其中定义了一个方法"Ping" 输入为PingRequest 和 PingResponse 其中PingRequest包含一个echo的属性,并集成一个BaseRequest的对象。
?
下面是使用php调用的代码:
?
?
最初我们调用的时候获取到的错误是找不到Ping方法,这个后来不确定是如何解决的。
后来加了SoapClient 的调用参数WSDL_CACHE_NONE让soap调用的时候不缓存wsd,以避免服务器修改了wsdl无法及时更新。设置此参数后,每次调用,都会重新load wsdl文件,因此监控java的log,将会拿到一个get请求,起初我们以为是调用wsdl的请求,后来发现,他是拿wsdl的请求。
?
过了这关后,会遇到如下错误:Unable to parse URL
?
这个原因经过google之后发现问题出在wsdl上面:<soap:address location="/soap/doorway/"/>
这里有的wsdl会:<soap:address location=""/>
这种方式使用java调用是没有问题的,但是使用php调用就是不行。再加上错误的提示信息,可以理解为,SoapClient没有智能的解析这个location,因此无法调用到soap的地址(这里称之为地址,其实我也不知道是什么意思,要想搞懂的可以看wsdl的协议。)
?
按照往上介绍的方法,在SoapClient调用里面增加参数:location =>"http://www.phpxiaoxin.com/soap/doorway"
但这种方法显然是不太好的,更好的方法是在生成的wsdl中就将location参数直接设置成绝对的url地址不要是相对的,也不要是空。
?
另外需要注意一个细节就是soap_version,分为:SOAP_1_1,SOAP_1_2 这两者发送的header是不一样的,一个是:text/xml一个是soap/xml,有的时候不兼容,就会将请求拒绝掉。
?
最后还有一个问题就是组装调用方法参数:
所调用方法应该组装的参数,主要看方法对应的wsdl中的input,对于Ping方法来说,就是PingRequest。
pingRequest继承了一个BaseRequest,那么相当于PingRequest有:token、username、password,以及自身的echo,因此将这些属性直接组装成array塞进去就ok了。
?
这里没有实验过一个方法对应多个输入对象应该如何处理,大家可以自己去试。而对已简单到String类型的输入参数来说,我这边的param为:$params = array('arg0'=>"hello111");
不过我的这个我使用的是另外一个wsdl,其输入参数的wsdl为(使用spring+cxf+aegis数据绑定生成):
?
?大家可以看看对应关系。是否能看出点什么规律。而对于复杂的对象,则可以层层的array进行嵌套。可以参开这个文章:PHP SOAP如何传入复杂对象
?
?
最后提醒一下:
php使用webservice的时候,需要确认开启了php_soap、php_curl的扩展(php.ini)
关于php的soap client 以及其option参数,可以参考官网:http://www.php.net/manual/en/soapclient.soapclient.php
?
使用php最好配置上xdebug以便可以调试,看到对象的值,相当明了,
SoapClient里面有发送的request的xml一看就知道是否有问题,以及问题出在哪里。
详情可以看一下xdebug等文章。
?
再就是php调用的时候我增加了try,catch,并且将exception输出,这样输出的结果似乎比直接跑异常要详细。
因此建议大家遇到问题的时候可以catch一下,以便能够看到详细的异常信息。
?
另外如果有对spring发布webservice以及spring+cxf发布webservice有问题的也可以找相关文章看一下。这里就不贴地址了。我也曾经介绍过cxf的。
?
总结一下,出错的缘由,由于本次webservice使用了手写xsd的方式,先手工写出了xsd,然后再生成的接口和对象,因此导致location设置不兼容。
?
?
?
参考:
unable-parse-url
nusoap-how-to-change-content-type-of-request
终于解决了PHP调用SOAP过程中的种种问题
?
分享一个xml在线格式化的工具:http://www.shell-tools.net/index.php?op=xml_format