【问题标题】:Large file transfer from HTTP server running Java Jersey Rest API从运行 Java Jersey Rest API 的 HTTP 服务器传输大文件
【发布时间】:2023-04-02 11:06:01
【问题描述】:

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

【问题讨论】:

  • 也许接受的答案也可以帮助你:stackoverflow.com/questions/10326460/…
  • 是否可以将其“外包”给 sftp 或 ftps?然后服务器端可以由标准的 ftp-server-application 管理。在客户端,肯定有现成的组件。
  • 因为它只是下载:让网络服务提供一个 http: 链接到一些只提供文件的网络服务器(例如 apache httpd)。如果你通过 apache httpd 代理它也可以为你做身份验证。
  • 你是如何解决这个问题的?

标签: java file jersey netty


【解决方案1】:

如果您遇到内存不足的问题,您应该检查您是如何处理正在下载的数据的。如果您使用 Jersey 的 ClientResponse,请确保您使用的是 getEntityInputStream() 而不是 getEntity()。这样,您可以流式传输数据,将其写入文件,然后将其丢弃,而不是让它在 Java 堆空间中堆积。

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

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

【讨论】:

    【解决方案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;
    }
    

    尝试使用 Steam 的客户端 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();
    }
    

    【讨论】:

      猜你喜欢
      • 2018-04-02
      • 2011-02-04
      • 1970-01-01
      • 1970-01-01
      • 2010-11-29
      • 1970-01-01
      • 1970-01-01
      • 2018-06-21
      • 2015-11-21
      相关资源
      最近更新 更多