2013-02-13 16 views
9

Java JDK 1.7およびJersey Webサービスフレームワークを使用してWebサービスを作成しています。私が提供しなければならないことの1つは、認証されたクライアントがある大きなデータファイル(1〜3 GB)をダウンロードできるようにする方法です。理想的には、これを一時停止してダウンロード可能なタイプを再開したいと思います。私はジャージーのマルチパートAPIを試して、クライアントマシン上で400 MBまで動作させることができましたが、それ以上のメモリ問題が発生しました。私はまた、同時のダウンロード要求に直面したときにサーバが失敗するかもしれないと心配しています。どのようにこれを行うことができますか? Nettyはオプションですか? Nettyを既存のJerseyベースのWebサービスにどのように統合できるかについてのあらゆる指針は?これを達成するのに役立つ他のフレーム作品がありますか?私はWebサービスのjavaを使用する必要があります。任意のポインタが役立ちます。Java Jersey Rest APIを実行しているHTTPサーバーからの大きなファイル転送

+0

たぶん受け入れ答えがあまりにもあなたを助けることができます。http://stackoverflow.com/questions/10326460/upload-a-large-file-using-jersey-client – Eich

+0

ですそれはsftpまたはftpsにこれを「アウトソーシングする」オプションですか?サーバー側は、標準のftp-server-applicationで管理することができます。クライアントサイドにはすぐに使用できるコンポーネントがあります。 – Fildor

+0

ダウンロードのみです:ウェブサービスに、そのファイルだけを提供するいくつかのウェブサーバー(たとえばapache httpd)へのhttp:リンクを提供させます。あなたがapache httpdを介してプロキシーするなら、あなたのために認証を行うこともできます。 –

答えて

6

メモリ不足の問題が発生している場合は、ダウンロードしているデータの処理方法を確認する必要があります。 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; 
} 

は、ファイルをダウンロードするために水蒸気を使用してクライアント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(); 
}