【问题标题】:how to decode Java stream in PHP如何在 PHP 中解码 Java 流
【发布时间】:2019-12-04 06:04:32
【问题描述】:

我请求了Walmart report API,结果将返回zip文件流。参考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文件但文件数据已损坏。可能是使用Java代码传输字节流之类的原因。这是如何转换字节流的问题。你能帮我吗? 顺便说一句,我已将流的部分剪切如下:

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: 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"
          ]

刚刚发现传输编码被分块了,不知道是不是这个问题?

【问题讨论】:

    标签: java php laravel zip walmart-api


    【解决方案1】:

    您解决了问题吗?下面的简单代码对我有用

        $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响应的正文,格式不可读 $filename zip 文件名从标题中获取。

    【讨论】:

    • 是的!我发现不是我的代码错了,只是文件错了。我有一些不同类型的商店。Emmm...有些可以打开文件,有些则称为数据损坏错误。
    【解决方案2】:

    似乎 Json 编码,您必须在 php 脚本中使用 json 对其进行解码,所以: json_decode(字符串,数组) string = 您收集的编码响应。 如果需要结果数据数组,则 array = True。

    2- 使用 header('Content-Type: application/json') (此标头在发送或接收响应之前最有用)

    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();
                        }
    

    希望对你有所帮助

    【讨论】:

    • 不!这是字节流而不是 json.Tx 你的帮助!
    • 跳过 json_decode 并尝试使用 var_dump() 然后发布结果。
    • 为了获得更好的帮助,您必须发布完整的回复。使用带有完整回复的在线解码器来查找文本格式。例如:conv.darkbyte.ru
    • 它太长了,我已经发布了部分结果,例如: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ì‡>顺便说一句,我已经添加了标题。api调用返回一个zip文件
    • 使用 gzdecode() 解码 zip 文件。我无法测试,因为您必须将完整的 zip 数据传递给函数,并且在此之前您必须获取 len 的 zip 数据,如下所示:$len = strlen($数据); $out=gzdecode($data,$len);有时你必须使用更多的解码来实现真正的结果搜索沃尔玛文档是最好的方法。分割解码的例子:gzdecode(hex2bin(base64_decode($data))),$len);
    猜你喜欢
    • 2019-07-12
    • 1970-01-01
    • 1970-01-01
    • 2011-07-01
    • 2011-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多