1

我正在针对Sonos 的 Music API (SMAPI)构建服务。有时我必须以以下格式发回响应:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
   <soap:Body>
      <soap:Fault>
         <faultcode>Client.NOT_LINKED_RETRY</faultcode>
         <faultstring>Link Code not found retry...</faultstring>
         <detail>
            <ExceptionInfo>NOT_LINKED_RETRY</ExceptionInfo>
            <SonosError>5</SonosError>
         </detail>
      </soap:Fault>
   </soap:Body>
</soap:Envelope>

我正在使用PHP SOAP 库构建我的服务,对于上述响应,我尝试抛出SoapFault这样的响应:

throw new SoapFault('Client.NOT_LINKED_RETRY', 'Link Code not found retry...');

但是当我尝试这个时,发回的响应如下所示:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
   <soap:Body>
      <soap:Fault>
         <faultcode>Client.NOT_LINKED_RETRY</faultcode>
         <faultstring>Link Code not found retry...</faultstring>
         <detail>
            <SonosError/>
         </detail>
      </soap:Fault>
   </soap:Body>
</soap:Envelope>

请注意,没有ExceptionInfo,那SonosError是空的。是否可以设置ExceptionInfoSonosError使用SoapFault?我尝试了各种方法,但无法使其正常工作,因此作为一种解决方法,我现在正在这样做:

http_response_code(500);
header("Content-type: text/xml");

$ret = '<?xml version="1.0" encoding="UTF-8"?>'."\n";
$ret .= '<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">';
$ret .= '<SOAP-ENV:Body>';
$ret .= '<SOAP-ENV:Fault>';
$ret .= '<faultcode>Client.NOT_LINKED_RETRY</faultcode>';
$ret .= '<faultstring>Link Code not found retry...</faultstring>';
$ret .= '<detail>';
$ret .= '<ExceptionInfo>NOT_LINKED_RETRY</ExceptionInfo>';
$ret .= '<SonosError>5</SonosError>';
$ret .= '</detail>';
$ret .= '</SOAP-ENV:Fault>';
$ret .= '</SOAP-ENV:Body>';
$ret .= '</SOAP-ENV:Envelope>'."\n";

echo $ret; exit;

不确定它是否相关,但可以在此处找到 WSDL 。

更新:当我尝试以下建议时:

$detail = new StdClass();
$detail->SonosError = 5;
$detail->ExceptionInfo = 'NOT_LINKED_RETRY';

throw new SoapFault(
  'Client.NOT_LINKED_RETRY',
  'Link Code not found retry...',
  NULL,
  $detail
);

我得到:

<detail>
  <customFault>
    <SonosError>5</SonosError>
    <ExceptionInfo>NOT_LINKED_RETRY</ExceptionInfo>
  </customFault>
</detail>

这几乎是我需要的,除了<customFault>标签。有没有办法摆脱它并直接拥有SonosErrorExceptionInfo进入<detail>

4

1 回答 1

3

您看不到ExceptionInfo标签的事实是因为它没有在 wsdl.xml 中定义。另一方面SonosError是定义。首先,为了填充SonosError你必须传递参数。

这里可以看出构造函数的参数比较多

SoapFault('code', 'string', 'actor', 'detail', 'name', 'header');

为了SonosError像这样通过调用

$detail = new StdClass(); 
$detail->SonosError = 5;
throw new SoapFault('Client.NOT_LINKED_RETRY', 'Link Code not found retry...', null, $details);

至于ExceptionInfo, wsdl 必须更改。就像现在一样,details标签由这个部分表示

<wsdl:message name="customFault">
    <wsdl:part name="customFault" element="tns:SonosError"/>
</wsdl:message> 

<xs:element name="SonosError" type="xs:int"/>

如果你用这些改变上面的部分,你就会得到你需要的东西。

<wsdl:message name="customFault">
   <wsdl:part name="customFault" type="tns:customFaultType" />
</wsdl:message>

<xs:complexType name="customFaultType">
   <xs:sequence>
      <xs:element name="SonosError" type="xs:int"/>
      <xs:element name="ExceptionInfo" type="xs:string"/>
   </xs:sequence>
</xs:complexType>

当然你添加参数,数组就变成了这样

$detail = new StdClass(); 
$detail->SonosError = 5;
$detail->ExceptionInfo = 'NOT_LINKED_RETRY';
于 2014-09-07T23:07:20.310 回答