10

Java JDK 1.7 と Jersey Web サービス フレームワークを使用して Web サービスを作成しています。私が提供する必要があるものの 1 つは、認証されたクライアントが特定の大きなデータ ファイル (1 ~ 3 GB) をダウンロードできるようにする方法です。理想的には、これを一時停止と再開タイプのダウンロード可能なオプションにしたいと考えています。jersey マルチパート API を試してみたところ、400 MB まではクライアント マシンで動作させることができましたが、それを超えるとメモリ不足の問題が発生しました。また、同時ダウンロード要求に直面した場合にサーバーがダウンするのではないかと心配しています。これを行う方法について何か考えはありますか?Netty はオプションですか? Netty を既存の Jersey ベースの Web サービスに統合する方法について何かアドバイスはありますか? これを達成するのに役立つ他のフレームワークはありますか? Web サービスには Java を使用する必要があります。どんな指針も役に立ちます。

4

2 に答える 2

6

メモリ不足の問題で立ち往生している場合は、ダウンロードしているデータをどのように処理しているかを確認する必要があります。JerseyのClientResponseを使用している場合は、getEntity()ではなくgetEntityInputStream()を使用していることを確認してください。このようにして、Javaヒープスペースにデータを蓄積させるのではなく、データをストリーミングしてファイルに書き込み、破棄することができます。

同時ダウンロードの懸念についてはお話しできませんが、Webサービスフレームワークを使用している場合は、適切に処理する必要があります。

どちらの問題についても、特定の実装、特にコードに関する詳細情報は、より良い応答を得るのに役立ちます。

于 2013-02-25T23:13:22.833 に答える
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;
}

ストリームを使用してファイルをダウンロードするクライアント 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();
}
于 2015-06-30T15:05:50.507 に答える