簡體   English   中英

Servlet - 如何從數據庫下載多個文件

[英]Servlet - how to download multiples files from database

我環顧四周,似乎將所有文件壓縮在一起就是要走的路。 如果是這種情況,這就是我想要做的設計。 如果有更有效的方法,請告訴我

  • 客戶端選擇下載的多個文件,然后單擊“下載”
  • servlet接收請求,然后將多個SELECT(文件保存為blob對象)語句寫入數據庫。

我可以創建BufferedOutputStream並將blob寫入不同的文件,我想在完成之后,我可以壓縮文件。 (這是拉鏈所有文件的好方法還是有更好更快的方法來實現這個?)完成拉鏈后,然后發送給客戶端(不知道怎么做,請任何人都知道如何,請幫助)請指出我的設計是否有任何缺陷。 我在上面發布了一些問題,並且真的很感激,任何人都可以幫我回答。 示例代碼非常棒。 非常感謝你,祝你新年快樂

基本上你只需要在response.getOutputStream()周圍構建一個新的ZipOutputStream ,然后將每個InputStream從DB添加為新的ZipEntry 為了提高性能,可以包住response.getOutputStream()BufferedOutputStream預先和所述InputStreamBufferedInputStream並使用byte[]緩沖液中。

這是一個基本的例子:

package com.example;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ZipFileServlet extends HttpServlet {

    private static final int DEFAULT_BUFFER_SIZE = 10240; // 10KB.
    private YourFileDAO yourFileDAO = YourDAOFactory.getYourFileDAO();

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException
    {
        String[] fileIds = request.getParameterValues("fileId");
        response.setContentType("application/zip");
        response.setHeader("Content-Disposition", "attachment; filename=\"allfiles.zip\"");
        ZipOutputStream output = null;
        byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];

        try {
            output = new ZipOutputStream(new BufferedOutputStream(response.getOutputStream(), DEFAULT_BUFFER_SIZE));

            for (String fileId : fileIds) {
                YourFileItem item = yourFileDAO.find(fileId);
                if (item == null) continue; // Handle yourself. The fileId may be wrong/spoofed.
                InputStream input = null;

                try {
                    input = new BufferedInputStream(item.getInputStream(), DEFAULT_BUFFER_SIZE);
                    output.putNextEntry(new ZipEntry(item.getName()));
                    for (int length = 0; (length = input.read(buffer)) > 0;) {
                        output.write(buffer, 0, length);
                    }
                    output.closeEntry();
                } finally {
                    if (input != null) try { input.close(); } catch (IOException logOrIgnore) { /**/ }
                }
            }
        } finally {
            if (output != null) try { output.close(); } catch (IOException logOrIgnore) { /**/ }
        }
    }

}

可以通過以下形式調用:

<form action="zipFile" method="post"> 
    <input type="checkbox" name="fileId" value="1"> foo.exe<br>
    <input type="checkbox" name="fileId" value="2"> bar.pdf<br>
    <input type="checkbox" name="fileId" value="3"> waa.doc<br>
    <input type="checkbox" name="fileId" value="4"> baz.html<br>
    <input type="submit" value="download zip">
</form>

這就是說,做到任何方式使用ByteArrayInputStream/ByteArrayOutputStream一些這里可能建議。 那些是由原始byte[] 當bytearrays中的所有文件(來自所有並發用戶!)的大小大於可用服務器內存時,您可能會冒應用程序中斷的風險。 您已有來自數據庫的流和響應的流。 只需將它們通過讀/寫循環中的小字節緩沖區進行管道傳輸即可。 您不需要在(引擎蓋下)大量字節緩沖區中獲取整個輸入流,然后將其寫入輸出流。

您不應該首先編寫文件。 您可以創建一個zip文件。

FileOutputStream fos = new FileOutputStream(zipFileName);
zipOutStream = new ZipOutputStream(fos);

然后,您可以為從數據庫中讀取的每個文件添加條目

ZipEntry zipEntry = new ZipEntry("NameOfFileToBeAdded");
zipOutStream.putNextEntry(zipEntry);
zipOutStream.write(byteArrayOfFileEntryData);
zipOutStream.closeEntry();

當然,寫入可以在循環中完成,因此byteArrayOfFileEntryData不會耗盡所有服務器內存。

添加完所有zip條目后,請關閉zip文件

zipOutStream.close();

創建zip文件后,您仍然需要將其返回給用戶。

編輯:一個選項是創建包裝響應輸出流的zip文件輸出流。 這樣,zip文件也不需要存儲在服務器上。 我沒有測試過這個選項。

zipOutStream = new ZipOutputStream(response.getOutputStream())

我們在單獨的機器上構建zip文件,該機器具有自己的Tomcat服務器以返回zip文件。 向用戶顯示一個“等待”頁面,顯示他們選擇的文件列表,這些文件會在壓縮所有文件后自動刷新以顯示zip文件的鏈接。 這樣,一旦用戶看到zip文件的大小,就可以重新考慮下載。 它還將zip文件保留在主應用程序服務器之外。

您不需要將數據庫blob寫入臨時文件,因為您可以在servlet中動態創建zip文件。 這包括完整的zip文件和所有條目。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM