如何解码 PHP 中的 Java 流
how to decode Java stream in PHP
我请求沃尔玛报告API,结果会返回zip文件stream.Refer到API文件,它给出了一个用Java代码实现的例子如下所示:
if (response.getStatus() == Response.Status.OK.getStatusCode() && response.hasEntity()) {
InputStream inputStream = (InputStream)response.getEntity();
try {
String header = response.getHeaderString("Content-Disposition");
if(header != null && !("").equals(header)) {
if(header.contains("filename")){
//header value will be something like:
//attachment; filename=10000000354_2016-01-15T23:09:54.438+0000.zip
int length = header.length();
String fileName = header.substring(header.indexOf("filename="),length);
System.out.println("filenameText " + fileName);
String [] str = fileName.split("=");
System.out.println("fileName: " + str[1]);
//replace "/Users/anauti1/Documents/" below with your values
File reportFile = new File("/Users/anauti1/Documents/" + str[1].toString());
OutputStream outStream = new FileOutputStream(reportFile);
byte[] buffer = new byte[8 * 1024];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outStream.write(buffer, 0, bytesRead);
}
IOUtils.closeQuietly(inputStream);
IOUtils.closeQuietly(outStream);
}
}
}
catch (Exception ex){
System.out.print("Exception: " + ex.getMessage());
}
}
但是,如果我使用 php 比如:
try {
$header = $resultInfo->getHeader('Content-Disposition');
if (!empty($header)) {
if (strpos($header, 'filename') !== false) {
$filename = substr($header, strpos($header, 'filename'));
$str = explode('=', $filename);
$body = $resultInfo->getBody();
$fp = fopen(storage_path("csv/{$str[1]}"), 'w');
fwrite($fp, $body);
fclose($fp);
}
}
} catch (\Exception $e) {
echo $e->getMessage();
}
会下载zip文件,但是文件数据是corrupt.It可能是字节流使用Java传输这样的原因code.It如何转换的问题bytes stream.Could 大家帮帮我好吗?
顺便说一下,我已经将部分流剪切如下:
b"PK\x03\x04\x14\x00\x00\x00\x08\x00\x10`‚OI^\x07RÒƒ\x04\x00Óo\x10\x004\x00\x00\x00ItemReport_10001023965_2019-12-02T115111.5040000.csvì½YsÛÈ–.ú~#î\x7F`ì‡>
Headers 像这样:
-headers: array:11 [
"accept-ranges" => array:1 [
0 => "bytes"
]
"content-disposition" => array:1 [
0 => "attachment; filename=ItemReport_10001023965_2019-12-02T115111.5040000.zip"
]
"content-type" => array:1 [
0 => "application/zip"
]
"x-tb" => array:1 [
0 => "0"
]
"expires" => array:1 [
0 => "Wed, 04 Dec 2019 02:33:20 GMT"
]
"cache-control" => array:1 [
0 => "max-age=0, no-cache, no-store"
]
"pragma" => array:1 [
0 => "no-cache"
]
"date" => array:1 [
0 => "Wed, 04 Dec 2019 02:33:20 GMT"
]
"transfer-encoding" => array:1 [
0 => "chunked"
]
"connection" => array:2 [
0 => "keep-alive"
1 => "Transfer-Encoding"
]
"set-cookie" => array:1 [
0 => "TS0d138f181a7bb55a8f02b54ee05b24ba9b4832fa32c8b0a9c4cb8592e5d1e4d02765d16ec77313d435d3ade8; Path=/; Secure"
]
]
-headerNames: array:11 [
"accept-ranges" => "Accept-Ranges"
"content-disposition" => "Content-Disposition"
"content-type" => "Content-Type"
"x-tb" => "X-Tb"
"expires" => "Expires"
"cache-control" => "Cache-Control"
"pragma" => "Pragma"
"date" => "Date"
"transfer-encoding" => "Transfer-Encoding"
"connection" => "Connection"
"set-cookie" => "Set-Cookie"
]
我刚刚发现 transfer-encoding 是 chuncked.I不确定是不是这个问题?
似乎 Json 已编码,您必须在 php 脚本中使用 json 对其进行解码,因此:
json_decode(字符串,数组)
string = 您收集的编码响应。
array = True 如果你想要结果数据数组。
2- 使用 header('Content-Type: application/json')
(这个 header 最有用 在 发送或接收响应之前)
3 - 错误处理:
json_last_error()
json_last_error_msg()
try {
$header = $resultInfo->getHeader('Content-Disposition');
if (!empty($header)) {
if (strpos($header, 'filename') !== false) {
$filename = substr($header, strpos($header, 'filename'));
$str = explode('=', $filename);
$body = $resultInfo->getBody();
$fp = fopen(storage_path("csv/{$str[1]}"), 'w');
##uncomment below line if response not valid may help you.
# header('Content-Type: application/json');
$dbody = json_decode($body,true);
fwrite($fp, $dbody);
fclose($fp);
}
}
} catch (\Exception $e) {
echo $e->getMessage();
}
希望能有所帮助
问题解决了吗?下面的简单代码对我有用
$fp = fopen('/your path where you store the zip file/'.$filename, 'w+');
if ($fp == FALSE){
print "File not opened<br>";
exit;
}
fwrite($fp, $response);
fclose($fp);
$response
是API响应的body,将是不可读的格式
$filename
zip 文件名来自 header。
我请求沃尔玛报告API,结果会返回zip文件stream.Refer到API文件,它给出了一个用Java代码实现的例子如下所示:
if (response.getStatus() == Response.Status.OK.getStatusCode() && response.hasEntity()) {
InputStream inputStream = (InputStream)response.getEntity();
try {
String header = response.getHeaderString("Content-Disposition");
if(header != null && !("").equals(header)) {
if(header.contains("filename")){
//header value will be something like:
//attachment; filename=10000000354_2016-01-15T23:09:54.438+0000.zip
int length = header.length();
String fileName = header.substring(header.indexOf("filename="),length);
System.out.println("filenameText " + fileName);
String [] str = fileName.split("=");
System.out.println("fileName: " + str[1]);
//replace "/Users/anauti1/Documents/" below with your values
File reportFile = new File("/Users/anauti1/Documents/" + str[1].toString());
OutputStream outStream = new FileOutputStream(reportFile);
byte[] buffer = new byte[8 * 1024];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outStream.write(buffer, 0, bytesRead);
}
IOUtils.closeQuietly(inputStream);
IOUtils.closeQuietly(outStream);
}
}
}
catch (Exception ex){
System.out.print("Exception: " + ex.getMessage());
}
}
但是,如果我使用 php 比如:
try {
$header = $resultInfo->getHeader('Content-Disposition');
if (!empty($header)) {
if (strpos($header, 'filename') !== false) {
$filename = substr($header, strpos($header, 'filename'));
$str = explode('=', $filename);
$body = $resultInfo->getBody();
$fp = fopen(storage_path("csv/{$str[1]}"), 'w');
fwrite($fp, $body);
fclose($fp);
}
}
} catch (\Exception $e) {
echo $e->getMessage();
}
会下载zip文件,但是文件数据是corrupt.It可能是字节流使用Java传输这样的原因code.It如何转换的问题bytes stream.Could 大家帮帮我好吗? 顺便说一下,我已经将部分流剪切如下:
b"PK\x03\x04\x14\x00\x00\x00\x08\x00\x10`‚OI^\x07RÒƒ\x04\x00Óo\x10\x004\x00\x00\x00ItemReport_10001023965_2019-12-02T115111.5040000.csvì½YsÛÈ–.ú~#î\x7F`ì‡>
Headers 像这样:
-headers: array:11 [
"accept-ranges" => array:1 [
0 => "bytes"
]
"content-disposition" => array:1 [
0 => "attachment; filename=ItemReport_10001023965_2019-12-02T115111.5040000.zip"
]
"content-type" => array:1 [
0 => "application/zip"
]
"x-tb" => array:1 [
0 => "0"
]
"expires" => array:1 [
0 => "Wed, 04 Dec 2019 02:33:20 GMT"
]
"cache-control" => array:1 [
0 => "max-age=0, no-cache, no-store"
]
"pragma" => array:1 [
0 => "no-cache"
]
"date" => array:1 [
0 => "Wed, 04 Dec 2019 02:33:20 GMT"
]
"transfer-encoding" => array:1 [
0 => "chunked"
]
"connection" => array:2 [
0 => "keep-alive"
1 => "Transfer-Encoding"
]
"set-cookie" => array:1 [
0 => "TS0d138f181a7bb55a8f02b54ee05b24ba9b4832fa32c8b0a9c4cb8592e5d1e4d02765d16ec77313d435d3ade8; Path=/; Secure"
]
]
-headerNames: array:11 [
"accept-ranges" => "Accept-Ranges"
"content-disposition" => "Content-Disposition"
"content-type" => "Content-Type"
"x-tb" => "X-Tb"
"expires" => "Expires"
"cache-control" => "Cache-Control"
"pragma" => "Pragma"
"date" => "Date"
"transfer-encoding" => "Transfer-Encoding"
"connection" => "Connection"
"set-cookie" => "Set-Cookie"
]
我刚刚发现 transfer-encoding 是 chuncked.I不确定是不是这个问题?
似乎 Json 已编码,您必须在 php 脚本中使用 json 对其进行解码,因此: json_decode(字符串,数组) string = 您收集的编码响应。 array = True 如果你想要结果数据数组。
2- 使用 header('Content-Type: application/json') (这个 header 最有用 在 发送或接收响应之前)
3 - 错误处理: json_last_error() json_last_error_msg()
try {
$header = $resultInfo->getHeader('Content-Disposition');
if (!empty($header)) {
if (strpos($header, 'filename') !== false) {
$filename = substr($header, strpos($header, 'filename'));
$str = explode('=', $filename);
$body = $resultInfo->getBody();
$fp = fopen(storage_path("csv/{$str[1]}"), 'w');
##uncomment below line if response not valid may help you.
# header('Content-Type: application/json');
$dbody = json_decode($body,true);
fwrite($fp, $dbody);
fclose($fp);
}
}
} catch (\Exception $e) {
echo $e->getMessage();
}
希望能有所帮助
问题解决了吗?下面的简单代码对我有用
$fp = fopen('/your path where you store the zip file/'.$filename, 'w+');
if ($fp == FALSE){
print "File not opened<br>";
exit;
}
fwrite($fp, $response);
fclose($fp);
$response
是API响应的body,将是不可读的格式
$filename
zip 文件名来自 header。