我在尝试将文件附加到我的soap请求时遇到问题。
我已经创建了一个可以处理该请求的工作类。但是我不知道在哪里附加文件。
这绝对是通过soapUI实现的原始查询。
Accept-Encoding: gzip,deflate
Content-Type: multipart/related; type="application/xop+xml"; start="<rootpart@soapui.org>"; start-info="text/xml"; boundary="----=_Part_35_1248651398.1559202098551"
SOAPAction: "http://tempuri.org/IFileStreamService/UploadFile"
MIME-Version: 1.0
Content-Length: 128611
Host: f19-fronter.itslbeta.com:4421
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
------=_Part_35_1248651398.1559202098551
Content-Type: application/xop+xml; charset=UTF-8; type="text/xml"
Content-Transfer-Encoding: 8bit
Content-ID: <rootpart@soapui.org>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header><wsse:Security s:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"><wsse:UsernameToken u:Id="UsernameToken-1682A89E6D8EA12AB6155920209854713"><wsse:Username>88b7e536-249a-4b65-a898-7e81db34ba9a</wsse:Username><wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">89f9577b-f693-49c0-840d-29a1338f1bfd</wsse:Password><wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">bNLifo+D9TkVgb2bL0flTw==</wsse:Nonce><u:Created>2019-05-30T07:41:38.546Z</u:Created></wsse:UsernameToken></wsse:Security>
<h:ExtensionId xmlns:h="http://tempuri.org/">5000</h:ExtensionId>
<h:Name xmlns:h="http://tempuri.org/">Lavrov1.jpg</h:Name>
</s:Header>
<s:Body>
<StreamMessage xmlns="http://tempuri.org/">
<Content>
<inc:Include href="cid:Lavrov1.jpg" xmlns:inc="http://www.w3.org/2004/08/xop/include"/>
</Content>
</StreamMessage>
</s:Body>
</s:Envelope>
------=_Part_35_1248651398.1559202098551
Content-Type: image/jpeg; name=Lavrov1.jpg
Content-Transfer-Encoding: binary
Content-ID: <Lavrov1.jpg>
Content-Disposition: attachment; name="Lavrov1.jpg"; filename="Lavrov1.jpg"
����JFIF��C
��C
����"��
��E
!1AQa"q2B�#R������3b��C $%r45S���D����3
现在,我需要用PHP复制它。 我让班级设法处理所有工作。
<?php
require dirname(__DIR__) . '/Helpers/XmlHelper.php';
class ApiFileUploader
{
/** @var string */
private $wsdl = 'https://f19-fronter.itslbeta.com:4421/FileStreamService.svc?wsdl';
/** @var string */
private $securityHeaderNS = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd';
/** @var string */
private $extraHeaderNS = 'http://tempuri.org';
/**
* @var MMLogger
*/
private $logger;
/**
* @var SoapClient
*/
private $apiClient;
/**
* @var MMConfig
*/
private $config;
public function __construct(MMConfig $config, MMLogger $logger)
{
$this->config = $config;
$this->logger = $logger;
}
public function uploadFile($fileName)
{
$this->logger->dbg('Attempt to upload file ' . $fileName, __METHOD__);
try {
$this->initApiClient($fileName);
$Content = new stdClass();
$xml = sprintf('<inc:Include href="cid:%s" xmlns:inc="http://www.w3.org/2004/08/xop/include"/>', $fileName);
$Content->content = new SoapVar($xml, XSD_ANYXML);
$request = new stdClass();
$request->Content = new SoapVar($Content, SOAP_ENC_OBJECT);
$attachment = new ImageObj(__DIR__ . '/../../files/'.$fileName);
$param = new SoapVar($attachment, SOAP_ENC_OBJECT, "attachment");
$param = new SoapParam($param, "param");
/** @noinspection PhpUndefinedMethodInspection */
$this->apiClient->UploadFile($request);
} catch (\Throwable $e) {
$this->logger->error($e->getMessage(), __METHOD__);
}
$this->logger->dbgXml(XmlHelper::formatXml($this->apiClient->__getLastRequest()), __METHOD__);
$this->logger->dbgXml($this->apiClient->__getLastResponse(), __METHOD__);
}
private function initApiClient($fileName)
{
$this->logger->dbg('Init API client', __METHOD__);
$this->apiClient = new SoapClient($this->wsdl, array('trace'=>1, 'stream_context' =>
stream_context_create(array('http'=>array(
'header'=> 'Accept-Encoding: gzip,deflate'.
'SOAPAction: http://tempuri.org/IFileStreamService/UploadFile'.
'Content-Type: image/jpeg; name=Lavrov1.jpg'.
'Content-Transfer-Encoding: binary'.
'Content-ID: <Lavrov1.jpg>'.
'Content-Disposition: attachment; name="Lavrov1.jpg"; filename="Lavrov1.jpg'.
'MIME-Version: 1.0'.
'Content-Length: 128611'
)))));
$this->initHeaders($fileName);
}
/**
* Build and load valid SOAP header
*
* @param MMConfig $config
* @return bool
*/
private function initHeaders($fileName)
{
$userName = new SoapVar(
$this->config->getApiUserName(),
XSD_STRING,
null,
null,
'Username',
$this->securityHeaderNS
);
$password = new SoapVar(
$this->config->getApiPassword(),
XSD_STRING,
null,
null,
'Password',
$this->securityHeaderNS
);
$token = new SoapVar(
array($userName, $password),
SOAP_ENC_OBJECT,
null,
null,
'UsernameToken',
$this->securityHeaderNS
);
$securityHeader = new SoapHeader(
$this->securityHeaderNS,
'Security',
new SoapVar(array($token), SOAP_ENC_OBJECT),
'1'
);
$extensionHeader = new SoapHeader(
$this->extraHeaderNS,
'ExtensionId',
new SoapVar(5000, XSD_INT)
);
$nameHeader = new SoapHeader(
$this->extraHeaderNS,
'Name',
new SoapVar($fileName, XSD_STRING)
);
return $this->apiClient->__setSoapHeaders(array(
$securityHeader,
$extensionHeader,
$nameHeader
));
}
}
class ImageObj{
function __construct($file, $mime = "") {
$this->file = $file;
$this->name = basename($file);
if (function_exists('mime_content_type')) {
$this->mime = mime_content_type($file);
} elseif (function_exists('finfo_open')) {
$this->mime = finfo_file(finfo_open(FILEINFO_MIME_TYPE), $file);
} else {
$this->mime = $mime;
}
$this->encoding = "base64";
$this->data = base64_encode(file_get_contents($file));
}
}
我从__getLastRequest获得的输出是:
[DBG] ApiFileUploader::uploadFile Attempt to upload file Lavrov1.jpg
[DBG] ApiFileUploader::initApiClient Init API client
[ERR] ApiFileUploader::uploadFile Bad Request
[DBG]
========== <?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://tempuri.org/" xmlns:ns2="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:ns3="http://tempuri.org">
<SOAP-ENV:Header>
<ns2:Security SOAP-ENV:mustUnderstand="1">
<ns2:UsernameToken>
<ns2:Username>88b7e536-249a-4b65-a898-7e81db34ba9a</ns2:Username>
<ns2:Password>89f9577b-f693-49c0-840d-29a1338f1bfd</ns2:Password>
</ns2:UsernameToken>
</ns2:Security>
<ns3:ExtensionId>5000</ns3:ExtensionId>
<ns3:Name>Lavrov1.jpg</ns3:Name>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<ns1:StreamMessage>
<ns1:Content>
<inc:Include href="cid:Lavrov1.jpg" xmlns:inc="http://www.w3.org/2004/08/xop/include"/>
</ns1:Content>
</ns1:StreamMessage>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope> =========
ApiFileUploader::uploadFile
[DBG]
========== =========
ApiFileUploader::uploadFile
主要问题是:如何正确解析标头? (我知道我解析错了。) 该base64编码文件放在哪里? (以我的情况为例)
soapUI的预期响应是:
HTTP/1.1 200 OK
Cache-Control: private
Transfer-Encoding: chunked
Content-Type: multipart/related; type="application/xop+xml";start="<http://tempuri.org/0>";boundary="uuid:360a3acb-26b4-4bdb-9b74-6fc679cec3da+id=2";start-info="text/xml"
Server: Microsoft-IIS/8.5
MIME-Version: 1.0
X-AspNet-Version: 4.0.30319
X-ITSL: ITSL641
X-Powered-By: ASP.NET
Date: Thu, 30 May 2019 07:41:41 GMT
--uuid:360a3acb-26b4-4bdb-9b74-6fc679cec3da+id=2
Content-ID: <http://tempuri.org/0>
Content-Transfer-Encoding: 8bit
Content-Type: application/xop+xml;charset=utf-8;type="text/xml"
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<u:Timestamp u:Id="_0">
<u:Created>2019-05-30T07:41:41.484Z</u:Created>
<u:Expires>2019-05-30T07:46:41.484Z</u:Expires>
</u:Timestamp>
</o:Security>
</s:Header>
<s:Body>
<FileStreamUploadResponse xmlns="http://tempuri.org/">
<FileId>17a13410-9010-4dd4-b396-c21b53be278d</FileId>
</FileStreamUploadResponse>
</s:Body>
</s:Envelope>
--uuid:360a3acb-26b4-4bdb-9b74-6fc679cec3da+id=2--