使用此代码我发出肥皂请求
$client = new SoapClient('http://example.com/soap/wsdl');
try {
$result = $client->myMethod();
} catch (Exception $e) {
echo $e->getMessage();
}
Run Code Online (Sandbox Code Playgroud)
有时(十分之一)会引发异常:
SoapFault异常:[HTTP]无法连接到主机
我的尝试
1)我寻找解决方案,我读到这个问题可能是由wsdl缓存引起的,我将其禁用php.ini:
soap.wsdl_cache_enabled = 0
soap.wsdl_cache_ttl = 0
Run Code Online (Sandbox Code Playgroud)
提出更少的例外
2)我试图添加到Windows的主机(它们在Windows上)dns的分辨率windows/system32/drivers/etc/hosts:
160.XX.XXX.XX example.com
Run Code Online (Sandbox Code Playgroud)
提出更少的例外
3)我还尝试禁用"Windows防火墙",
提出更少的例外
4)我还尝试在php.ini中增加default_socket_timeout
default_socket_timeout = 90
Run Code Online (Sandbox Code Playgroud)
什么也没有变
这个问题
服务器肥皂似乎没有问题.它也可以从其他网站使用没有问题.还有什么我可以做的吗?
我的设置
PHP 5.6
Apache 2.4
Windows Server 2012
UPDATE
经过多次测试,我认为问题出在网络上,肥皂服务器背后是反向代理,问题出现在代理中.
我目前正在研究Spring soap服务器项目.我从Spring的http://spring.io/guides/gs/producing-web-service/开始使用Spring的入门指南来构建基本的SOAP服务.
默认的SOAP协议是SOAP v1.1.有没有办法可以通过注释将协议设置为v1.2?
我@BindingType(javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_BINDING)在@Endpoint课上尝试了注释,但似乎没有用.
我也尝试@Endpoint(value = SOAPBinding.SOAP12HTTP_BINDING)设置它,但是这在启动日志中看不到
INFO --- [nio-8080-exec-1] o.s.ws.soap.saaj.SaajSoapMessageFactory :
Creating SAAJ 1.3 MessageFactory with SOAP 1.1 Protocol
Run Code Online (Sandbox Code Playgroud)
当然,如果我向服务器发布SOAP请求,我会收到以下错误
2015-01-19 15:50:17.610 ERROR 20172 --- [nio-8080-exec-1] c.sun.xml.internal.messaging.saaj.soap : SAAJ0533: Cannot create message: incorrect content-type for SOAP version. Got application/soap+xml;
charset=utf-8, but expected text/xml
2015-01-19 15:50:17.611 ERROR 20172 --- [nio-8080-exec-1] c.sun.xml.internal.messaging.saaj.soap :
SAAJ0535: Unable to internalize message
2015-01-19 15:50:17.617 ERROR 20172 --- [nio-8080-exec-1] a.c.c.C.[.[.[.[messageDispatcherServlet] :
Servlet.service() for servlet [messageDispatcherServlet] in context …Run Code Online (Sandbox Code Playgroud) 我正在准备SOAP服务器并使用以下代码生成我的WSDL:
//(... Controller action code ...)
if (key_exists('wsdl', $params)) {
$autodiscover = new AutoDiscover();
$autodiscover->setClass('WebServiceClass')
->setUri('http://server/webserver/uri');
$autodiscover->handle();
} else {
$server = new Server(null);
$server->setUri($ws_url);
$server->setObject($this->getServiceLocator()->get('MyController\Service\WebServiceClass'));
$server->handle();
}
//(... Controller action code ...)
Run Code Online (Sandbox Code Playgroud)
但在我的一个WebService方法中,我有一个Array类型的参数,其中每个元素的类型为"MyOtherClass",如下所示:
/**
* Add list of MyOtherClass items
*
* @param MyOtherClass[] $items
*
* @return bool
*/
function add($items) {
// Function code here
}
Run Code Online (Sandbox Code Playgroud)
当我尝试生成WSDL时,我得到以下错误:
PHP Warning: DOMDocument::loadXML(): Empty string supplied as input in /<zend framweork path>/Server/vendor/zendframework/zendframework/library/Zend/Soap/Server.php on line 734
Run Code Online (Sandbox Code Playgroud)
或者这个例外:
Cannot add a complex …Run Code Online (Sandbox Code Playgroud) 这可能是一个非常懒惰的问题,但我保证不是.我已经尝试了几天才能使这个工作,但我不能.
我得到了一个WSDL文件,我需要在PHP中为它创建一个SOAP服务.谁能告诉我这样做的正确方法是什么?
服务的接收者期望在调用getMember方法时返回"User"对象.
这是WSDL
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="http://tempuri.org/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" targetNamespace="http://tempuri.org/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:types>
<s:schema elementFormDefault="qualified" targetNamespace="http://tempuri.org/">
<s:element name="getMember">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="memCode" type="s:string"/>
</s:sequence>
</s:complexType>
</s:element>
<s:element name="getMemberResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="getMemberResult" type="s:string"/>
</s:sequence>
</s:complexType>
</s:element>
<s:element name="getMemberByUsernameAndPassword">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="username" type="s:string"/>
<s:element minOccurs="0" maxOccurs="1" name="password" type="s:string"/>
</s:sequence>
</s:complexType>
</s:element>
<s:element name="getMemberByUsernameAndPasswordResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="getMemberByUsernameAndPasswordResult" type="s:string"/>
</s:sequence>
</s:complexType>
</s:element>
<s:element name="insertMember">
<s:complexType>
<s:sequence>
<s:element …Run Code Online (Sandbox Code Playgroud) 我正在建立一个SOAP Web服务,它接受XML输入并且必须返回自定义XML输出.所有这些都在WSDL中定义.我为此应用soapServer(直到有人说它有错误阻止我实现我的目标:-)).
我还没有能够返回自定义XML:我得到一些似乎基于WSDL的结果,标准根元素名称等于输入XML加上"响应".实际上,这让我感到惊讶,作为一个侧面问题,我想知道为什么会这样,以及它是否可以受到影响.当然,在创建响应时以某种方式使用WSDL定义是一件好事,但正如我所说,我不知道如何在响应中获得自定义XML.
我得到了这个:
WSDL
<?xml version="1.0" encoding="UTF-8"?>
<definitions
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://pse/"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
name="PSE"
targetNamespace="http://pse/">
<types>
<xs:schema>
<xs:import namespace="http://pse/" schemaLocation="PSE.xsd"/>
</xs:schema>
</types>
<message name="MI102Req">
<part name="cdhead" type="tns:cdhead_T"/>
<part name="instr" type="tns:instr_T"/>
</message>
<message name="Res">
<part name="cdhead" type="tns:cdhead_T"/>
</message>
<portType name="MIPortType">
<operation name="mi102">
<input message="tns:MI102Req"/>
<output message="tns:Res"/>
</operation>
</portType>
<binding name="MIBinding" type="tns:MIPortType">
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="mi102">
<soap:operation soapAction="http://www.testURL/test_soap.php#mi102"/>
<input>
<soap:body use="literal" namespace="http://pse/"/>
</input>
<output>
<soap:body use="literal" namespace="http://pse/"/>
</output>
</operation>
</binding>
<service name="PSE">
<port name="MIPortType" binding="tns:MIBinding">
<soap:address location="http://www.testURL/test_soap.php"/>
</port>
</service>
</definitions>
Run Code Online (Sandbox Code Playgroud)
输入XML …
所以错误是:
PHP Fatal error: Procedure 'sup:set_availability' not present in XMLSoapServer.php
我在开发环境(MAMP)上收到此错误.
这是由无效的XML字符串引起的,其中'sup'命名空间未定义:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<SOAP-ENV:Envelope xmlns:SOAPSDK1="http://www.w3.org/2001/XMLSchema"
xmlns:SOAPSDK2="http://www.w3.org/2001/XMLSchema-instance"
xmlns:SOAPSDK3="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<sup:set_availability>
<SetAvailability>
...
</SetAvailability>
</sup:set_availability>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Run Code Online (Sandbox Code Playgroud)
(这是一个外部请求,所以我不能只是去纠正来源 - 我能做到,但至少不能在短时间内通知.)
问题是我有两个处理相同请求的服务器.没有错误.所以我的任务是找出原因:)
一些细节:
到目前为止我检查过的事情:
服务器1的版本为2.6.26,服务器2的版本为2.7.7 - 请求的工作方式就像一个魅力我的开发环境有lixml2版本2.8.0 - 并且确实抛出了致命的错误.
我的猜测是(或者是)libxml2导致错误 - 但是我找不到关于这个主题的任何资源 - 我也没有成功将我的本地libxml2版本降级到2.6或2.7.
那么......对此有何看法?
我想扩展,SoapClient以便在访问WSDL时在内部执行此操作:
curl -L -E /location/of/cert.pem -c /tmp/location/of/cookie.jar https://web-service-provider/servicename?wsdl
Run Code Online (Sandbox Code Playgroud)
我有类似这样的SOAP请求:
$serviceUrl = 'https://service-url';
$wsdl = $serviceUrl . '?wsdl';
$proxyServiceUrl = 'http://localhost/myproxy.php?url=$serviceUrl';
$proxyWsdl = 'http://localhost/myproxy.php?url=$wsdl';
$options = array(
'cache_wsdl' => WSDL_CACHE_NONE,
'encoding' => 'utf-8',
'soap_version' => SOAP_1_1,
'exceptions' => true,
'trace' => true,
'location' => $proxyServiceUrl
);
$client = new SoapClient($proxyWsdl, $options);
$params = array( /* */ );
$client->someOperation($params);
Run Code Online (Sandbox Code Playgroud)
如您所见,除代理位外,一切都非常标准.
代理的原因
我编写代理来满足Web服务提供者的要求,即通过名为siteminder的身份验证系统处理包括WSDL在内的所有端点.
代理的功能非常简单,如果用linux命令行curl编写,它将是这样的:
curl -L -E /location/of/cert.pem -c /tmp/location/of/cookie.jar https://web-service-provider/servicename?wsdl
Run Code Online (Sandbox Code Playgroud)
确切地说:
* Follow all redirections
* specify location …Run Code Online (Sandbox Code Playgroud) 我正在使用PHP SoapServer类,并尝试将纯XML放在SOAP响应的主体中.
情况1:
我的WSDL有
<element name="getDataResponse" type="xsd:string"/>
Run Code Online (Sandbox Code Playgroud)
我编码响应
return new SoapVar($my_xml,XSD_ANYXML)
Run Code Online (Sandbox Code Playgroud)
PHP SoapClient说
SOAP-ERROR: Encoding: Violation of encoding rules
Run Code Online (Sandbox Code Playgroud)
案例2:
WSDL
<element name="getDataResponse" type="xsd:string"/>
Run Code Online (Sandbox Code Playgroud)
响应编码
return new SoapVar($my_xml,XSD_STRING)
Run Code Online (Sandbox Code Playgroud)
响应XML全部<编码为< 和> as>
案例3:
WDSL
<element name="getDataResponse">
<complexType>
...
</complexType>
</element>
Run Code Online (Sandbox Code Playgroud)
其中complexType对应要返回的XML结构
响应编码
return new SoapVar($my_xml,XSD_ANYXML)
Run Code Online (Sandbox Code Playgroud)
现在返回类型是一个对象,而不是XML字符串
案例4
除了编码为SOAP_ENC_OBJECT之外,与案例3相同.结果将是对象.
请帮忙!我怎样才能将纯XML文本作为SOAP响应的主体?
我对Soap在"创建服务方面"方面比较陌生,所以请提前预测我正在修改的任何术语.
是否可以从使用PHP的SoapServer类设置的远程过程肥皂服务返回PHP数组?
我有一个WSDL(盲目地按照教程构建),部分看起来像这样
<message name='genericString'>
<part name='Result' type='xsd:string'/>
</message>
<message name='genericObject'>
<part name='Result' type='xsd:object'/>
</message>
<portType name='FtaPortType'>
<operation name='query'>
<input message='tns:genericString'/>
<output message='tns:genericObject'/>
</operation>
</portType>
Run Code Online (Sandbox Code Playgroud)
我正在调用的PHP方法是命名查询,看起来像这样
public function query($arg){
$object = new stdClass();
$object->testing = $arg;
return $object;
}
Run Code Online (Sandbox Code Playgroud)
这让我可以打电话
$client = new SoapClient("http://example.com/my.wsdl");
$result = $client->query('This is a test');
Run Code Online (Sandbox Code Playgroud)
和结果转储看起来像
object(stdClass)[2]
public 'result' => string 'This is a test' (length=18)
Run Code Online (Sandbox Code Playgroud)
我想从查询方法返回本机PHP数组/集合.如果我更改我的查询方法以返回一个数组
public function query($arg) {
$object = array('test','again');
return $object;
}
Run Code Online (Sandbox Code Playgroud)
它被序列化为客户端的对象.
object(stdClass)[2]
public 'item' =>
array
0 => …Run Code Online (Sandbox Code Playgroud) 在PHP中,我想知道SOAP调用的方法是什么.这是一个要了解的样本......
$soapserver = new SoapServer();
$soapserver->setClass('myClass');
$soapserver->handle();
Run Code Online (Sandbox Code Playgroud)
我想知道的是将在handle()中执行的方法的名称
谢谢 !!
soapserver ×10
php ×9
soap ×7
wsdl ×3
soap-client ×2
encoding ×1
fault ×1
ntlm ×1
siteminder ×1
spring-ws ×1
zend-soap ×1