从运行Java Jersey Rest API的HTTP服务器传输大文件

时间:2013-02-13 23:01:54

标签: java file jersey netty

我正在使用Java JDK 1.7和Jersey Web服务框架编写Web服务。我需要提供的一件事是允许经过身份验证的客户端下载某些大型数据文件(1-3 GB)。理想情况下,我希望这是一个暂停和恢复类型可下载选项。我尝试了泽西多部分API,并且能够让它在我的客户端机器上工作高达400 MB,但除此之外它遇到了内存不足的问题。我还担心服务器在遇到同步下载请求时可能会失败。有关如何做到这一点的任何想法? Netty是一个选择吗?关于如何将Netty集成到基于泽西岛的现有Web服务中的任何指示?是否有其他框架可用于帮助实现此目的?我必须使用java作为Web服务。任何指针都会有所帮助。

2 个答案:

答案 0 :(得分:6)

如果您遇到内存不足问题,则应检查处理正在下载的数据的方式。如果您使用的是Jersey的ClientResponse,请确保使用的是getEntityInputStream()而不是getEntity()。这样,您可以流式传输数据,将其写入文件,并将其抛在一边,而不是让它在Java堆空间中构建。

我无法真正谈论您的同时下载问题,但如果您使用的是Web服务框架,则应该正确处理。

对于这两个问题,有关具体实施的更多信息(尤其是代码)将帮助您获得更好的响应。

答案 1 :(得分:2)

服务器和客户端都必须支持HTTP分块编码,这允许用户使用HTTP流式传输数据。以下代码适用于Jersey 2.11。

要下载大文件,请在服务器上尝试:

@GET
@Path("/files/{fileName}")
@Produces(MediaType.APPLICATION_OCTET_STREAM)

public StreamingOutput getFile(@PathParam("fileName") final String fileName)  throws Exception  {
  //create instance of StreamingOutput here
  return streamingOutput;
}

尝试使用steams下载文件的客户端GET请求。

public String getFileReq(File outFile) throws IOException {

  client = ClientBuilder.newClient(new ClientConfig());
  client.property(ClientProperties.REQUEST_ENTITY_PROCESSING, "CHUNKED");
  WebTarget target = client.target(URI)
  OutputStream fileOutputStream = new FileOutputStream(outFile);
  InputStream fileInputStream = target.request().get(InputStream.class);
  writeFile(fileInputStream, fileOutputStream);    

}

public static void writeFile(InputStream fileInputStream, OutputStream outputStream) throws IOException {
try {
  byte[] buffer = new byte[1024];
  int bytesRead;

  while((bytesRead = fileInputStream.read(buffer)) !=-1) {
      outputStream.write(buffer, 0, bytesRead);
  }

  fileInputStream.close();
  outputStream.flush();
 } catch (IOException e) {
   e.printStackTrace();
 } finally {
   outputStream.close();
}