【问题标题】:How do I work with a REST API in Java that returns a zip file?如何在 Java 中使用返回 zip 文件的 REST API?
【发布时间】:2021-06-01 07:09:23
【问题描述】:

我熟悉使用 HttpURLConnection 类在 Java 中发出 GET 请求的基础知识。在返回类型为 JSON 的正常情况下,我会这样做:

    URL obj = new URL(myURLString);
    HttpURLConnection con = (HttpURLConnection) obj.openConnection();
    con.setRequestMethod("GET");
    int responseCode = con.getResponseCode();
    if (responseCode == HttpURLConnection.HTTP_OK) {
        BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
        String inpLine;
        StringBuffer resp = new StringBuffer();

        while ((inpLine = in.readLine()) != null) {
            resp.append(inputLine);
        }
        in.close();
        System.out.println(resp.toString());                          
    } else { System.out.println("Request failed");

但是,我正在尝试使用的当前端点会发回一个包含各种类型文件的 zip 文件。在这种情况下,“Content-Type”将是“application/octet-stream”。用上面的代码访问那个端点会导致控制台中写入一堆符号(不确定它叫什么)。即使在 Postman 中,我也看到了相同的情况,并且仅当我在发出请求时使用“发送和下载”选项时才有效,这会提示我保存响应并获得 zip 文件。

有关如何通过 Java 访问 API 并下载返回的 zip 文件的任何帮助?提前谢谢你。

编辑:我打算对 zip 文件执行的操作是将其保存在本地,然后我的程序的其他部分将使用其中的内容。

【问题讨论】:

  • 压缩文件是二进制文件。因此,您不能使用基于字符的 reader(您使用的是InputStreamReader)来阅读内容。按原样获取输入流(因为它们是基于 nbyte 的)。
  • 你需要用那个 zip 文件做什么?您是否需要将其保存在某个地方,或者您对某个内容(对里面的内容)感兴趣?
  • 我需要把它保存在某个地方。端点上有一个参数,我可以指定保存位置。

标签: java api rest httpurlconnection bufferedreader


【解决方案1】:

我想你可以试试这个 API:

try (ZipInputStream zis = new ZipInputStream(con.getInputStream())) {
        
    ZipEntry entry; // kinda self-explained (a file inside zip)

    while ((entry = zis.getNextEntry()) != null) {
         // do whatever you need :)
         // this is just a dummy stuff
        System.out.format("File: %s Size: %d Last Modified %s %n",
                    entry.getName(), entry.getSize(),
                    LocalDate.ofEpochDay(entry.getTime() / MILLS_IN_DAY));
    }
}

无论如何,你都会得到一个流,所以你可以做所有 java IO API 允许你做的事情。

例如,要保存文件,您可以执行以下操作:

// I am skipping here exception handling, closing stream, etc.
byte[] zipContent = zis.readAllBytes();
new FileOutputStream("some.zip").write(zipContent);

要对 zip 中的文件执行某些操作,您可以执行以下操作:

 // again, skipping exceptions, closing, etc.
 // also, you'd probably do this in while loop as in the first example
 // so let's say we get ZipEntry 
 ZipEntry entry = zis.getNextEntry();
 
 // crate OutputStream to extract the entry from zip file
 final OutputStream os = new FileOutputStream("c:/someDir/" + entry.getName());
 
 
 byte[] buffer = new byte[1024];
 int length;
 
 //read the entry from zip file and extract it to disk
 while( (length = zis.read(buffer)) > 0) {
     os.write(buffer, 0, length);
 }

 // at this point you should get your file

我知道,这是一种低级 API,您需要处理流、字节等,也许有一些库允许用一行代码或其他东西来做到这一点:)

【讨论】:

  • 我不知道这是API,谢谢!但是,我仍在寻找一种方法来保存整个 zip 文件,或者最好保存一个 ZipEntry,这样我就可以遍历所有文件,并且只根据某些条件保存我想要的文件。
  • @Ars 更新:)
  • 非常感谢!唯一需要注意的是,ReadAllBytes() 可能不会被 ZipInputStream 类继承,具体取决于 jdk 版本。尽管如此,我对保存整个 zip 不感兴趣,所以这对我有用。非常感激! @ikos23
猜你喜欢
  • 1970-01-01
  • 2021-09-18
  • 1970-01-01
  • 2023-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-20
相关资源
最近更新 更多