Resteasy 下载的损坏的 ZIP 文件
Corrupted ZIP file from Resteasy download
问题是,从 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在文件中添加了HTTPheader,所以最终大小为 1843 字节 + header 部分)。这是我的 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 响应 header:
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
编辑:在问题中整合评论信息。
对于这个问题没有找到简单的解决方案,作为解决方法,我创建了一个 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
参数是简单的编码令牌,包含时间戳,用于对称安全。它避免了 servlet 中 authentication/role 逻辑的完整端口(如果 servlet URL 没有在不到 3 秒内从 REST 方法调用,请求将 return 为 400) .
这不是一个优雅的解决方案,但至少现在文件不再损坏。
P.S。顺便提一下:WinRAR
会很好地处理损坏的文件(还有 7zip
版本 9.2),Windows Explorer
和最后一个版本的 7zip
无法打开它.
问题是,从 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在文件中添加了HTTPheader,所以最终大小为 1843 字节 + header 部分)。这是我的 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 响应 header:
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
编辑:在问题中整合评论信息。
对于这个问题没有找到简单的解决方案,作为解决方法,我创建了一个 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
参数是简单的编码令牌,包含时间戳,用于对称安全。它避免了 servlet 中 authentication/role 逻辑的完整端口(如果 servlet URL 没有在不到 3 秒内从 REST 方法调用,请求将 return 为 400) .
这不是一个优雅的解决方案,但至少现在文件不再损坏。
P.S。顺便提一下:WinRAR
会很好地处理损坏的文件(还有 7zip
版本 9.2),Windows Explorer
和最后一个版本的 7zip
无法打开它.