responseオブジェクトを使用してファイルをダウンロードする

3008 ワード

仕事の中でJavaを使ってファイルをダウンロードする情況に出会って、いくつかの特殊な情況に対して長い間悩んで、やっと解決して、ダウンロードの問題に対する探究の過程と中間で出会った穴を記録します.
一、responseを使ってダウンロードする
responseオブジェクトを使用した通常のダウンロード
response.reset();
response.setHeader("Content-Disposition", "attachment;filename="+URLEncoder.encode(fileName, "UTF-8"));
response.setHeader("Connection", "close");
response.setHeader("Content-Type", "application/octet-stream");
		
OutputStream ops = null;
FileInputStream fis =null;
byte[] buffer = new byte[8192];
int bytesRead = 0;
		
try {
    ops = response.getOutputStream();
    fis = new FileInputStream(path);
    while((bytesRead = fis.read(buffer, 0, 8192)) != -1){
         ops.write(buffer, 0, bytesRead);
    }
    ops.flush();
    } catch (IOException e) {
	e.printStackTrace();
    } finally {
	try {
	    if(fis != null){
		fis.close();
	    }
	    if(ops != null){
		ops.close();
	    }
	} catch (IOException e) {
	    e.printStackTrace();
	}
}

二、複数のファイルをダウンロードする場合
responseを使用して複数のファイルのダウンロードを開始し、バックエンドで処理した結果、実現できませんでした.
ピット1:1つのrequestは対応する1つのresponseしか返さない
したがって、responseオブジェクトを使用して複数のファイルをダウンロードすることはできません.opsを閉じずにファイルに強引に出力すると、ファイルは読めません.Excelを使用して読み取り可能に復元するには、最初のファイルのみが存在します.
その後、複数のリクエストを送信しようとAjaxを使用してリクエストを複数回送信しようとします.
ピット2:Ajaxを使用してファイルのダウンロードを要求することはできません
Ajaxの戻りタイプはjson、text、html、xmlなどのタイプであり、ストリームタイプではないため、ファイルダウンロードは実現できません.
したがって、フォームまたはiframeを非表示にする方法しか使用できません.
フォームメソッドを非表示にするには、次の手順に従います.
jQuery('
' + '' + '' + '
').appendTo('body').submit();
では、コミット時にすべて加算され、一度だけコミットされるという問題があります.
最終的な解決方法:
ページは複数の隠しiframeを追加して、循環はsrcを設定して、それぞれload
三、Ajax要求実現ファイルダウンロード方法
1、非表示フォームを使用して、非表示フォームを発行する
2、window.open()またはwindow.location.href()メソッドの使用
3、隠しiframeを使用して、srcはバックエンドに必要なアドレスを指す
四、Ajaxはファイルのダウンロードができないが、ファイルの内容を得ることができ、ファイルはメモリに保存され、ディスクに保存できない.JavaScriptはディスクと対話できないため、jsはブラウザのダウンロード処理メカニズムとプログラムを呼び出すことができず、ブラウザにブロックされます.
五、responseのgetWriter()メソッドは、2回連続してページにストリームを出力する場合、2回目のストリームには1回目のストリームが含まれるので、response.reset()またはresponse.resetBuffer()メソッドでリセットする必要があります
response.reset()
Clears any data that exists in the buffer as well as the status code and headers. If the response has been committed, this method throws an IllegalStateException.
response.reset()の使用には、responseの開いたストリームが閉じてからresetを使用できないという条件があります.
resetBuffer()
Clears the content of the underlying buffer in the response without clearing headers or status code. If the response has been committed, this method throws an
IllegalStateException
resetBufferメソッドとresetメソッドの違いは,ヘッダとステータスコードがクリアされていないことである.
六、複数のファイルのダウンロードは、複数のファイルを1つの圧縮パッケージに圧縮してからダウンロードすることもできる.
JAva複数のファイルをzipパッケージにまとめてダウンロードしたインスタンス