Resteasy下载损坏的ZIP文件

时间:2016-05-24 15:38:38

标签: java rest http resteasy

问题是,从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传递给Response,但问题仍然存在。有什么提示吗?

哦,我也试过通过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

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

1 个答案:

答案 0 :(得分:0)

找不到这个问题的简单解决方案,因为我已经创建了一个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在REST方法的不到3秒内没有被调用,请求将返回400)。 不是一个优雅的解决方案,但至少现在该文件不再被破坏。

P.S。顺便说一句,就像一个注释:WinRAR将处理损坏的文件(7zip版本9.2),Windows Explorer7zip的最后一个版本无法打开它。