如何使用 JAX-RS 从 Java 服务器端返回 Zip 文件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22881478/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 18:39:08  来源:igfitidea点击:

How can I return a Zip file from my Java server-side using JAX-RS?

javajerseyjax-rsfilestreamoutputstream

提问by prince

I want to return a zipped file from my server-side java using JAX-RS to the client.

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

I tried the following code,

我尝试了以下代码,

@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();
}

But i'm getting exception as below,

但我得到如下异常,

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

What is wrong and how can I fix this?

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

回答by Opal

I'm not sure I it's possible in Jersey to just return a stream as result of annotated method. I suppose that rather stream should be opened and content of the file written to the stream. Have a look at thisblog post. I guess You should implement something similar.

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

回答by efernandez

You are delegating in Jersey the knowledge of how to serialize the ZipOutputStream. So, with your code you need to implement a custom MessageBodyWriter for ZipOutputStream. Instead, the most reasonable option might be to return the byte array as the entity.

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

Your code looks like:

您的代码如下所示:

@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();
}

In this example I use FileUtils from Apache Commons IOto convert File to byte[], but you can use another implementation.

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

回答by orangegiraffa

In Jersey 2.16 file download is very easy

在 Jersey 2.16 文件下载很容易

Below is the example for the ZIP file

以下是 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();
}

回答by Anil Bachola

You can write the attachment data to StreamingOutput class, which Jersey will read from.

您可以将附件数据写入 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();
}