【问题标题】:Corrupted ZIP file from Resteasy download来自 Resteasy 下载的损坏的 ZIP 文件
【发布时间】:2016-09-21 22:27:15
【问题描述】:

问题是,从 REST 服务下载 zip 文件后,我得到了类似的内容:

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Disposition: attachment; filename=Report_request_2681.zip
Content-Type: application/octet-stream
Content-Length: 1843
Date: Tue, 24 May 2016 15:24:39 GMT

PK etc etc... my real zip file bytes

生成的zip文件是正确的(尝试直接从服务器复制,大小为1843字节),故障出在下载方式(resteasy在文件中添加HTTP头,所以最终大小为1843字节+标题部分)。这是我的resteasy 实现(我已经删除了无影响的部分):

@Produces(MediaType.APPLICATION_OCTET_STREAM)
@Path("/download/{fileName}")
Response getRequestedFile(
        @Context HttpServletRequest httpRequest,
        @PathParam("fileName") String fileName
);

    //... bla bla bla method and authentication stuff

    //Prepare a file object with file to return
    File file = new File(myPath);
    if (!file.exists()) {
        return Response.status(Response.Status.NOT_FOUND).build();
    }

    try {
        return Response.ok(FileUtils.readFileToByteArray(file), MediaType.APPLICATION_OCTET_STREAM_TYPE).header("Content-Disposition", "attachment; filename=\"" + cleanFileName + "\"").build();
    } catch (IOException ex) {
        return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
    }

我正在使用resteasy 2.1.0 GA(我无法升级它)。方法readFileToByteArray 取自org.apache.commons.io.FileUtils。我尝试将内容设置为 text/plain 或 application/zip 并将 FileInputStream 传递给响应,但问题仍然存在。有什么建议吗?

哦,我也尝试使用简单的文本文件通过 REST 方法下载...同样的问题,在下载文件的开头我有 HTTP 响应标头:

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Disposition: attachment; filename="Report_request_2681"
Content-Type: application/octet-stream
Content-Length: 16550
Date: Wed, 25 May 2016 07:03:20 GMT

...rest of my txt file

编辑:问题中的综合评论信息。

【问题讨论】:

  • 你说你得到的是“我真正的 zip 文件字节”——那么这些字节和原始 zip 文件有什么区别?它们的长度一样吗?
  • Content-Length 是否与文件大小一致?使用 application/octet-stream 很好。字节开始没问题(PK ...),也许手动上传和下载使用文本模式而不是二进制模式的FTP,在\n\r\n之间转换。尝试其他文件。
  • 该文件(没有标题部分是 1843 字节)。我已经通过直接从服务器获取它来检查它,而不是通过 REST 服务下载。这部分无疑是resteasy添加的。
  • 要明确一点,如果我打开下载的文件,它会得到 HTTP/1.1 200 OK 服务器:Apache-Coyote/1.1 Content-Disposition: attachment; filename=Report_request_2681.zip Content-Type: application/octet-stream Content-Length: 1843 Date: Tue, 24 May 2016 15:24:39 GMT 部分,没有通过 ws 下载它只有 PK... 部分(其中是正确的 zip 文件)
  • FileUtils.readFileToByteArray 是做什么的;如果这是您自己的代码:显示它,如果是标准代码:哪个库?

标签: java rest http resteasy


【解决方案1】:

没有为这个问题找到简单的解决方案,作为一种解决方法,我创建了一个 servlet 来下载文件(从新 URL,压缩文件没有损坏),所以我更改了我的 resteasy 实现做一个重定向:

....
String redirectPath = StringUtils.substringBefore(httpRequest.getRequestURL().toString(), "restws") + "download?fileName=" + fileName + "&actionId=" + actionRequestId + "&check=" + encodedString;
return Response.seeOther(URI.create(redirectPath)).build();

其中check 参数是简单编码令牌,包含时间戳,用于simmetric 安全性。它避免了我在 servlet 中的身份验证/角色逻辑的完整端口(如果 servlet URL 未在 3 秒内从 REST 方法调用,则请求将返回 400)。 不是一个优雅的解决方案,但至少现在文件不再损坏。

附:顺便提一下:WinRAR 可以很好地处理损坏的文件(还有7zip 9.2 版),Windows Explorer 和最后一个版本的7zip 无法打开它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多