【问题标题】:How can I return a Zip file from my Java server-side using JAX-RS?如何使用 JAX-RS 从我的 Java 服务器端返回 Zip 文件?
【发布时间】:2018-12-20 01:26:28
【问题描述】:

我想使用 JAX-RS 从我的服务器端 java 返回一个压缩文件到客户端。

我尝试了以下代码,

@GET
public Response get() throws Exception {

    final String filePath = "C:/MyFolder/My_File.zip";

    final File file = new File(filePath);
    final ZipOutputStream zop = new ZipOutputStream(new FileOutputStream(file);

    ResponseBuilder response = Response.ok(zop);
    response.header("Content-Type", "application/zip");
    response.header("Content-Disposition", "inline; filename=" + file.getName());
    return response.build();
}

但我遇到了如下异常,

SEVERE: A message body writer for Java class java.util.zip.ZipOutputStream, and Java type class java.util.zip.ZipOutputStream, and MIME media type application/zip was not found
SEVERE: The registered message body writers compatible with the MIME media type are:
*/* ->
  com.sun.jersey.core.impl.provider.entity.FormProvider

出了什么问题,我该如何解决?

【问题讨论】:

    标签: java jersey jax-rs filestream outputstream


    【解决方案1】:

    您在泽西岛委派有关如何序列化 ZipOutputStream 的知识。因此,您需要使用您的代码为 ZipOutputStream 实现自定义 MessageBodyWriter。相反,最合理的选择可能是将字节数组作为实体返回。

    您的代码如下所示:

    @GET
    public Response get() throws Exception {
        final File file = new File(filePath);
    
        return Response
                .ok(FileUtils.readFileToByteArray(file))
                .type("application/zip")
                .header("Content-Disposition", "attachment; filename=\"filename.zip\"")
                .build();
    }
    

    在此示例中,我使用 Apache Commons IO 中的 FileUtils 将 File 转换为 byte[],但您可以使用其他实现。

    【讨论】:

    • 这对我来说是唯一可行的解​​决方案。我用 ZipOutputStream 尝试了所有发布的解决方案,只是 Apache FileUtils 有效。谢谢!
    【解决方案2】:

    您可以将附件数据写入 StreamingOutput 类,Jersey 将从该类中读取。

    @Path("/report")
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public Response generateReport() {
        String data = "file contents"; // data can be obtained from an input stream too.
        StreamingOutput streamingOutput = outputStream -> {
            ZipOutputStream zipOut = new ZipOutputStream(new BufferedOutputStream(outputStream));
            ZipEntry zipEntry = new ZipEntry(reportData.getFileName());
            zipOut.putNextEntry(zipEntry);
            zipOut.write(data); // you can set the data from another input stream
            zipOut.closeEntry();
            zipOut.close();
            outputStream.flush();
            outputStream.close();
        };
    
        return Response.ok(streamingOutput)
                .type(MediaType.TEXT_PLAIN)
                .header("Content-Disposition","attachment; filename=\"file.zip\"")
                .build();
    }
    

    【讨论】:

    • 谢谢!我唯一需要改变的是 zipOut.write 需要字节。
    【解决方案3】:

    在 Jersey 2.16 文件下载非常容易

    以下是 ZIP 文件的示例

    @GET
    @Path("zipFile")
    @Produces("application/zip")
    public Response getFile() {
        File f = new File(ZIP_FILE_PATH);
    
        if (!f.exists()) {
            throw new WebApplicationException(404);
        }
    
        return Response.ok(f)
                .header("Content-Disposition",
                        "attachment; filename=server.zip").build();
    }
    

    【讨论】:

      【解决方案4】:

      我不确定在泽西岛是否可以只返回一个流作为带注释的方法的结果。我想应该打开流并将文件的内容写入流。看看this 博客文章。我想你应该实现类似的东西。

      【讨论】:

        猜你喜欢
        • 2015-10-03
        • 1970-01-01
        • 2012-07-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-02-26
        相关资源
        最近更新 更多