如何在JAX-RS中设置响应标头,以便用户看到Excel的下载弹出窗口?

2022-08-31 20:27:10

我编写了使用REST JAX-RS生成Excel文件的代码,并确认生成的Excel文件位于GlassFish服务器目录中。

但我的目标是当用户单击按钮(生成Excel.xls)时,我希望显示下载弹出窗口,询问用户是否保存或打开.xls文件,就像任何其他Web服务下载任何类型的文件一样。

根据我的搜索,步骤是:

  1. 生成 Excel .xls (DONE)

  2. 将 Excel 写入流

  3. 在 JAX-RS 文件中,将响应标头设置为类似

    字符串文件名 = “Blah_Report.xls”;response.setHeader(“Content-Disposition”, “attachment;文件名=“ + 文件名);

我的问题是我在JAX-RS文件中完成所有这些工作,我没有可用的HttpServletResponse对象。

根据将响应标头添加到 JAX-RS Web 服务中的答案

他说:

您可以通过web服务中的@Context注释注入对实际HttpServletResponse的引用,并使用addHeader()等添加标头。

如果没有示例代码,我无法真正弄清楚这到底意味着什么。


答案 1

您不需要 HttpServletResponse 即可在响应上设置标头。您可以使用javax.ws.rs.core.Response来做到这一点。只需使方法返回响应而不是实体:

return Response.ok(entity).header("Content-Disposition", "attachment; filename=\"" + fileName + "\"").build()

如果你仍然想使用HttpServletResponse,你可以把它注入到其中一个类字段,或者使用属性,或者注入方法参数:

@Path("/resource")
class MyResource {

  // one way to get HttpServletResponse
  @Context
  private HttpServletResponse anotherServletResponse;

  // another way
  Response myMethod(@Context HttpServletResponse servletResponse) {
      // ... code
  }
}

答案 2
@Context ServletContext ctx;
@Context private HttpServletResponse response;

@GET
@Produces(MediaType.APPLICATION_OCTET_STREAM)
@Path("/download/{filename}")
public StreamingOutput download(@PathParam("filename") String fileName) throws Exception {
    final File file = new File(ctx.getInitParameter("file_save_directory") + "/", fileName);
    response.setHeader("Content-Length", String.valueOf(file.length()));
    response.setHeader("Content-Disposition", "attachment; filename=\""+ file.getName() + "\"");
    return new StreamingOutput() {
        @Override
        public void write(OutputStream output) throws IOException,
                WebApplicationException {
            Utils.writeBuffer(new BufferedInputStream(new FileInputStream(file)), new BufferedOutputStream(output));
        }
    };
}