【问题标题】:How can I reuse JAX-RS Response into HttpServletResponse?如何在 HttpServletResponse 中重用 JAX-RS 响应?
【发布时间】:2017-01-11 10:36:59
【问题描述】:

我有一个向我的 Rest API 发出请求的 Servlet,我希望它通过 HttpServletResponse 将 API 响应内容返回给最终用户。

内容实际上是一个要下载的 .xls 文件,我将其放入带有 StreamingOutput 对象的响应中。

我该怎么做?我无法将响应转换为 HttpServletResponse

Rest API 方法:

@GET
@Produces( MediaType.APPLICATION_JSON )
@Path("bla")
public Response getTopicByName() {

    final Workbook wb = new HSSFWorkbook();
    StreamingOutput stream = new StreamingOutput() {
        @Override
        public void write(OutputStream output) throws IOException, WebApplicationException {
            wb.write(output);
        }
    };
    responseBuilder = responseBuilder.entity(stream);
    responseBuilder = responseBuilder.status(Response.Status.OK);
    responseBuilder = responseBuilder.header("Content-Disposition", "attachment; filename=" + device + ".xls");

    return responseBuilder.build();
}

Servlet POST 方法:

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    Client client = ClientBuilder.newClient();
    WebTarget target = client.target(url);
    Response res = target. request().get();
    if (res.getStatus() == 200) {
        // how to put res stream into response stream ?
        ServletOutputStream stream = response.getOutputStream();
    }
    client.close();
}

编辑:

我尝试了 TedTrippin 方法,在找到从 Response 中恢复 InputStream 的方法后,效果很好。

但我不断收到损坏的 xls 文件。这很烦人。当我直接从浏览器发出请求时,我没有得到那些损坏的文件。 有任何线索吗?

POST 方法:

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    Client client = ClientBuilder.newClient();
    WebTarget target = client.target(url + param + format);
    Response res = target.request().get();
    if (res.getStatus() == 200) {
        response.setHeader("Content-Disposition", "attachment; filename=test.xls");
        InputStream in = res.readEntity(InputStream.class);
        ServletOutputStream out = response.getOutputStream();
        byte[] buffer = new byte[1024];
        while (in.read(buffer) >= 0) {
            out.write(buffer);
        }
        out.flush();
    }
    client.close();
}

【问题讨论】:

    标签: java rest servlets jakarta-ee


    【解决方案1】:

    最简单的方法是读取响应流并将其直接写入响应输出流。要么使用 IOUtils 或 Guava 中的库函数,要么使用纯 java...

    try (InputStream in = ...;
         OutputStream out = ...) {
      byte[] buffer = new byte[1024];
      while (in.read(buffer) >= 0)
        out.write(buffer);
    } catch (IOException ex) {
      ...
    }
    

    更好的(取决于您的观点)方法是将响应读取/保存为临时文件,然后您可以将其返回或将其写入输出流。

    第三种方法是创建管道,但我认为这不适用于此处。

    【讨论】:

      猜你喜欢
      • 2015-02-23
      • 1970-01-01
      • 2013-12-15
      • 1970-01-01
      • 2013-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-06
      相关资源
      最近更新 更多