我无法在php中将SOAP响应转换为Array.
这是代码
 $response = $client->__doRequest($xmlRequest,$location,$action,1);
这是SOAP响应.
<soap:envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:body>
<searchflightavailability33response xmlns="http://FpwebBox.Fareportal.com/Gateway.asmx">
<searchflightavailability33result>
    <Fareportal><FpSearch_AirLowFaresRS><CntKey>1777f5a7-7824-46ce-a0f8-33d5e6e96816</CntKey><Currency CurrencyCode="USD"/><OriginDestinationOptions><OutBoundOptions><OutBoundOption segmentid="9W7008V21Feb14"><FlightSegment etc....
    </searchflightavailability33result>
</searchflightavailability33response>
</soap:body>
</soap:envelope>;
我使用以下方法转换为数组,但我得到空输出.
1.echo '<pre>';print_r($client__getLastResponse());
2.echo '<pre>';print_r($response->envelope->body->searchflightavailability33response);
3.echo '<pre>';print_r($client->SearchFlightAvailability33($response));
     4.simplexml_load_string($response,NULL,NULL,"http://schemas.xmlsoap.org/soap/envelope/");  
5.echo '<pre>';print_r($client->SearchFlightAvailability33($response));
请指教.
我当前的实现是利用ClientBase类为第三方API的WCF调用创建一个通道.此第三方API需要对X509Certificate2证书以及ClientCredentials进行身份验证.
public class HeaderAdder : ContextBoundObject, IClientMessageInspector
{
    public bool RequestFailedDueToAuthentication;
    public string UserName { get; set; }
    public string Password { get; set; }
    public object BeforeSendRequest(ref Message request, IClientChannel channel)
    {
        var property = new UserNameHeader
        {
            Password = Password,
            UserName = UserName
        };
        request.Headers.Add(MessageHeader.CreateHeader("UserNameHeader", "test", property));
        return null;
    }
    public void AfterReceiveReply(ref Message reply, object correlationState)
    {
        RequestFailedDueToAuthentication = reply.ToString().Contains("ErrorCode>-4<");
    }
}
public class CustomEndpointBehavior : IEndpointBehavior
{
    private readonly HeaderAdder _headerAdder;
    public CustomEndpointBehavior(HeaderAdder headerAdder)
    {
        _headerAdder …我正在阅读php类SoapServer的文档,但没有发现将在SoapServer构造函数中传递的选项的描述:
还有一个功能选项可以设置为
SOAP_WAIT_ONE_WAY_CALLS, 
SOAP_SINGLE_ELEMENT_ARRAYS, 
SOAP_USE_XSI_ARRAY_TYPE.
这个选项值有什么区别?
我是一个我无法控制的SOAP服务的客户端(在.NET中实现).该服务提供WSDL.我使用Apache CXF从WSDL生成java客户端(具体来说,我使用的是Maven的cxf-codegen-plugin,它使用了wsdl2java).
但是,当我实例化生成的服务类时,会记录以下警告:
Sep 04, 2014 5:18:00 PM [com.sun.xml.internal.ws.policy.EffectiveAlternativeSelector]  selectAlternatives
WARNING: WSP0075: Policy assertion "{http://schemas.xmlsoap.org/ws/2005/07/securitypolicy}TransportBinding" was evaluated as "UNKNOWN".
Sep 04, 2014 5:18:00 PM [com.sun.xml.internal.ws.policy.EffectiveAlternativeSelector]  selectAlternatives
WARNING: WSP0019: Suboptimal policy alternative selected on the client side with fitness "UNKNOWN".
但是客户端工作正常 - 我使用该服务没有任何问题.但是,我对这些错误感到困惑.
错误是关于WSDL中的这个安全策略,我认为它说它无法理解:
<wsp:Policy wsu:Id="soap11_policy" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
  <wsp:ExactlyOne>
    <wsp:All>
      <sp:TransportBinding xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
        <wsp:Policy>
          <sp:TransportToken>
            <wsp:Policy>
              <sp:HttpsToken RequireClientCertificate="false"/>
            </wsp:Policy>
          </sp:TransportToken>
          <sp:AlgorithmSuite>
            <wsp:Policy>
              <sp:Basic256/>
            </wsp:Policy>
          </sp:AlgorithmSuite>
          <sp:Layout>
            <wsp:Policy>
              <sp:Strict/>
            </wsp:Policy>
          </sp:Layout>
        </wsp:Policy>
      </sp:TransportBinding>
    </wsp:All>
  </wsp:ExactlyOne>
</wsp:Policy>
但据我所知,这是一个完全普通的政策,并没有什么不寻常之处.当然应该理解?我该如何修复此警告?
为了记录,这里是如何调用wsdl2java(摘自pom.xml).
该-exsh trueARG和cxf-rt-bindings-soap …
使用此代码我发出肥皂请求
$client = new SoapClient('http://example.com/soap/wsdl');
try {
    $result = $client->myMethod();
} catch (Exception $e) {
    echo $e->getMessage();
}
有时(十分之一)会引发异常:
SoapFault异常:[HTTP]无法连接到主机
我的尝试
1)我寻找解决方案,我读到这个问题可能是由wsdl缓存引起的,我将其禁用php.ini:
soap.wsdl_cache_enabled = 0
soap.wsdl_cache_ttl = 0
提出更少的例外
2)我试图添加到Windows的主机(它们在Windows上)dns的分辨率windows/system32/drivers/etc/hosts:
160.XX.XXX.XX example.com
提出更少的例外
3)我还尝试禁用"Windows防火墙",
提出更少的例外
4)我还尝试在php.ini中增加default_socket_timeout
default_socket_timeout = 90
什么也没有变
这个问题
服务器肥皂似乎没有问题.它也可以从其他网站使用没有问题.还有什么我可以做的吗?
我的设置
PHP 5.6
Apache 2.4
Windows Server 2012
UPDATE
经过多次测试,我认为问题出在网络上,肥皂服务器背后是反向代理,问题出现在代理中.
我的Spring Web服务客户端有这个自定义解析器来捕获SoapFaults:
public class MySoapFaultResolver extends SoapFaultMessageResolver implements FaultMessageResolver 
{
    private static Logger logger = Logger.getLogger( MySoapFaultResolver.class);
    @Override
    public void resolveFault(WebServiceMessage wsm) throws IOException 
    {
        logger.debug("entering");
//      SOAPMessage soapMessage = (SOAPMessage) wsm;   cant cast to this
        SoapMessage soapMessage = (SoapMessage) wsm;
        if( soapMessage == null) {
            logger.debug("soapMessage is null");
        } else {
            logger.debug("soapMessage is not null");
            QName om_fc = soapMessage.getFaultCode();
            String om_frs = soapMessage.getFaultReason();
            logger.debug("om_fc:" + om_fc);
            logger.debug("om_frs:" + om_frs);
            if( soapMessage.getSoapBody() == null) {
                logger.debug("soap body is null");               
            } …我正在发送SOAP请求,服务器抱怨SOAPAction标头为空.我想我做对了,但显然我不是.Wireshark显示它没有设置.
@Test
public void testLogin() throws Exception {
    StringBuffer loginXml = new StringBuffer();
    loginXml.append("<soapenv:Envelope xmlns:soapenv=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:ns=\"http://example.com/xyz/2010/08\">");
    loginXml.append("  <soapenv:Header>");
    loginXml.append("    <ns:loginOperationDetails>");
    loginXml.append("    </ns:loginOperationDetails>");
    loginXml.append("  </soapenv:Header>");
    loginXml.append("  <soapenv:Body>");
    loginXml.append("    <ns:LogIn>");
    loginXml.append("      <ns:logInInfo>");
    loginXml.append("        <ns:CustomerAccountId>customer1</ns:CustomerAccountId>");
    loginXml.append("        <ns:Username>JDoe</ns:Username>");
    loginXml.append("        <ns:Password>abc123</ns:Password>");
    loginXml.append("      </ns:logInInfo>");
    loginXml.append("    </ns:LogIn>");
    loginXml.append("  </soapenv:Body>");
    loginXml.append("</soapenv:Envelope>");
    WebServiceTemplate webServiceTemplate = new WebServiceTemplate();
    MessageFactory msgFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
    SaajSoapMessageFactory newSoapMessageFactory = new SaajSoapMessageFactory(msgFactory);
    webServiceTemplate.setMessageFactory(newSoapMessageFactory);
    String uri = "http://xyz.example.com/xyz_1.0/membership.svc/ws";
    webServiceTemplate.setDefaultUri(uri);
    StreamSource source = new StreamSource(new StringReader(loginXml.toString()));
    StreamResult result = new StreamResult(System.out);
    boolean resultReturned = false;
    try { …我需要向多个不同的Web服务发送多个请求并接收结果.问题是,如果我逐个发送请求,只要我需要单独发送和处理所有请求.
我想知道如何立即发送所有请求并收到结果.
如下面的代码所示,我有三个主要方法,每个方法都有自己的子方法.每个子方法向其关联的Web服务发送请求并接收结果;因此,例如,为了接收Web服务9的结果,我必须等到1到8的所有Web服务都完成,这需要很长时间才能发送所有请求一个接一个,并收到他们的结果.
如下所示,没有任何方法或子方法彼此相关,所以我可以将它们全部调用并以任何顺序接收它们的结果,唯一重要的是接收每个子方法的结果并填充它们相关列表.
private List<StudentsResults> studentsResults = new ArrayList();
private List<DoctorsResults> doctorsResults = new ArrayList();
private List<PatientsResults> patientsResults = new ArrayList();
main (){
    retrieveAllLists();
}
retrieveAllLists(){
     retrieveStudents();
     retrieveDoctors();
     retrievePatients();
}
retrieveStudents(){
    this.studentsResults = retrieveStdWS1();   //send request to Web Service 1 to receive its  list of students
    this.studentsResults = retrieveStdWS2();  //send request to Web Service 2 to receive its  list of students
    this.studentsResults = retrieveStdWS3(); //send request to Web Service 3 to receive its  list of students
}
retrieveDoctors(){
   this.doctorsResults …我正在使用他们提供的wsdl向Canada Post发送一个电话,其中包含以下部分:
<!-- group-id and transmit-shipment are mutually exclusive -->
<xsd:element name="groupIdOrTransmitShipment" abstract="true" />
<xsd:element name="group-id" type="tns:GroupIDType" substitutionGroup="tns:groupIdOrTransmitShipment"/>
<xsd:element name="transmit-shipment" type="xsd:boolean" fixed="true" substitutionGroup="tns:groupIdOrTransmitShipment"/>
<xsd:complexType name="ShipmentType">
    <xsd:all>
        <xsd:element ref="tns:groupIdOrTransmitShipment" />
        <xsd:element name="quickship-label-requested" type="xsd:boolean" minOccurs="0"/>
        <xsd:element name="cpc-pickup-indicator" type="xsd:boolean" fixed="true" minOccurs="0"/>
        <xsd:element name="requested-shipping-point" type="tns:PostalCodeType" minOccurs="0"/>
        <xsd:element name="shipping-point-id" type="tns:OutletIDType" minOccurs="0" />
        <xsd:element name="expected-mailing-date" type="xsd:date" minOccurs="0"/>
        <xsd:element name="delivery-spec" type="tns:DeliverySpecType"/>
        <xsd:element name="return-spec" type="tns:ReturnSpecType" minOccurs="0"/>
    </xsd:all>
</xsd:complexType>
在他们的代码示例中,他们扩展了Soap类并覆盖了__doRequest()Soap方法,如下所示:
/*
 Need to override SoapClient because the abstract element 'groupIdOrTransmitShipment' is expected to be in the request …soap-client ×10
soap ×7
php ×4
java ×2
wsdl ×2
c# ×1
cxf ×1
go ×1
java-ee ×1
jax-ws ×1
rest-client ×1
soapserver ×1
spring ×1
spring-ws ×1
wcf ×1
web-services ×1
wsdl2java ×1
xml ×1