如何将JAX-RS响应重用到HttpServletResponse中?

时间:2017-01-11 10:36:59

标签: java rest servlets java-ee

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

内容实际上是一个要下载的.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();
}

1 个答案:

答案 0 :(得分: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) {
  ...
}

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

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