【问题标题】:Download file from REST service using JAX-RS client使用 JAX-RS 客户端从 REST 服务下载文件
【发布时间】:2015-10-03 13:17:46
【问题描述】:

我正在尝试使用 JAX-RS 从 REST 服务下载文件。 这是我的代码,它通过发送 GET 请求来调用下载:

private Response invokeDownload(String authToken, String url) {
    // Creates the HTTP client object and makes the HTTP request to the specified URL
    Client client = ClientBuilder.newClient();
    WebTarget target = client.target(url);

    // Sets the header and makes a GET request
    return target.request().header("X-Tableau-Auth", authToken).get();
}

但是,我在将 Response 转换为实际的 File 对象时遇到了问题。所以我所做的如下:

public File downloadWorkbook(String authToken, String siteId, String workbookId, String savePath)
        throws IOException {
    String url = Operation.DOWNLOAD_WORKBOOK.getUrl(siteId, workbookId);
    Response response = invokeDownload(authToken, url);

    String output = response.readEntity(String.class);
    String filename; 
// some code to retrieve the filename from the headers
    Path path = Files.write(Paths.get(savePath + "/" + filename), output.getBytes());
    File file = path.toFile();
    return file;
}

创建的文件无效,我调试了代码并注意到输出包含这样的字符串(大得多):

PK͢�F������[ Superstore.twb�ysI�7������������d�m3��f���

看起来像二进制。显然代码有问题。

如何从 Response 对象中获取 HTTP 响应正文作为字符串?



编辑: 引用关于 HTTP 响应的 REST API 参考:

响应正文

以下之一,具体取决于工作簿的格式:

.twb 格式的工作簿内容(内容类型:application/xml
.twbx 格式的工作簿内容(Content-Type:application/octet-stream

【问题讨论】:

  • 您的文件似乎不是文本文件。因此,从它创建一个字符串不是一个好主意。而是使用 response.getInputStream() 并将其写入文件,例如使用 Apache Commons 的 IOUtils.copy(in, out)
  • 这可能会有所帮助stackoverflow.com/a/12251265/2294429
  • @SebastianS 你应该回答这个问题。
  • 那个输出看起来很像一个 zip 文件。
  • @Samuel 我不确定这是否是唯一原因(检索到的文件实际上仍可能是文本文件)。现在添加这个作为答案。

标签: java jax-rs


【解决方案1】:

正如您自己注意到的,您在这里处理的是二进制数据。所以你不应该从你的回复中创建一个字符串。最好获取输入流并将其通过管道传输到您的文件中。

Response response = invokeDownload(authToken, url);
InputStream in = response.readEntity(InputStream.class);
Path path = Paths.get(savePath, filename);
Files.copy(in, path);

【讨论】:

  • 如何获取 InputStream?没有方法 getInputStream()
  • 更新了我的答案。一开始没有查看确切的 API。
【解决方案2】:

1) 我假设您已经清楚“二进制文件”和“文本文件”之间的区别。而且您只能将后者捕获为“字符串”。

2) Sebastian 为您提供了捕获二进制文件的绝佳建议(+1,Sebastian!)。非常重要:在这种情况下,您应该始终设置 MIME 类型 (Content-Type: xxx/yyy)。 Here 是另一个可能有用的链接。

3) 最后,在某些情况下,您可能想要将“二进制”数据视为文本。这就是电子邮件附件与 SMTP(一种文本协议)一起使用的方式。在这些情况下,您想使用Base64 Encoding。例如:JAX-RS | Download PDF from Base64 encoded data

【讨论】:

  • 2) 我改变了这样的请求:target.request().accept(MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_XML).header("X-Tableau-Auth", authToken).get()
猜你喜欢
  • 2023-04-04
  • 2013-06-03
  • 2016-12-06
  • 2014-02-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-03
相关资源
最近更新 更多