2017-01-11 2 views
0

У меня есть сервлет, который обращается к моему API-интерфейсу Rest, и я хочу, чтобы он возвращал контент ответа API конечному пользователю через HttpServletResponse.Как повторно использовать ответ JAX-RS в HttpServletResponse?

Содержимое на самом деле является файлом .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(); 
} 

EDIT:

Я попытался TedTrippin метод и после обнаружения способ восстановить InputStream из Response, он работал хорошо.

Но я продолжаю получать поврежденные файлы 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

Простейший способ состоит в чтении поток ответа и записать его прямо в выходной поток ответа. Либо использовать библиотечную функцию от IOUtils или гуавы или чистой Java ...

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

приятнее (в зависимости от вашей точки зрения), как бы прочитать/сохранить ответ как временный файл, то вы можете вернуть то или написать это к выходному потоку.

Третий подход заключается в создании трубы, но я не думаю, что это применимо здесь.

+0

Спасибо, сработало. Но у меня есть еще одна проблема :( – Phoste