java 使用 servlet,如何从数据库下载多个文件并将它们压缩以供客户端下载
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15962172/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using a servlet, how do you download multiple files from a database and zip them for client download
提问by Lani1234
I have a jsp/servlet web app in which the client can choose a "course" and an "assignment" via dropdown boxes, and then click a button to download all the files in the database that are listed under that course/assignment combination. The servlet code isn't quite working, as the zip file is not being sent to the browser as an attachment. I do have working code for downloading one file at a time, but something is getting stuck with this code for zipping the files. All the files in the database are actually zip files themselves, so I am trying to zip up a bunch of zip files. I didn't think this would require that they be treated differently than zipping any other format of files. Can anyone see what is missing? Here is my doGet method code in the servlet that handles the downloading. Much of this code was found here on stackoverflow. Please note that the FileSubmitted object is my DOA containing all the file info for each file in the database, including the Blob itself:
我有一个 jsp/servlet web 应用程序,客户端可以在其中通过下拉框选择“课程”和“作业”,然后单击按钮下载数据库中在该课程/作业组合下列出的所有文件。servlet 代码不能正常工作,因为 zip 文件没有作为附件发送到浏览器。我确实有用于一次下载一个文件的工作代码,但是此代码用于压缩文件时遇到了一些问题。数据库中的所有文件实际上都是 zip 文件本身,所以我试图压缩一堆 zip 文件。我认为这不需要将它们与压缩任何其他格式的文件区别对待。任何人都可以看到缺少什么吗?这是我在处理下载的 servlet 中的 doGet 方法代码。大部分代码都可以在 stackoverflow 上找到。请注意,FileSubmitted 对象是我的 DOA,其中包含数据库中每个文件的所有文件信息,包括 Blob 本身:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
List<FileSubmitted> fileList = new ArrayList<FileSubmitted>();
String course= request.getParameter("course");
String assignment = request.getParameter("assignment");
java.sql.PreparedStatement pstmt = null;
java.sql.Connection conn = null;
ResultSet rs;
String queryString;
try {
conn = ConnectionManager.getConnection();
conn.setAutoCommit(false);
queryString = "SELECT * FROM files WHERE courseID=\""+course+"\" AND assignmentID=\""+assignment+"\";";
pstmt = conn.prepareStatement(queryString);
rs = pstmt.executeQuery(queryString);
while(rs.next())
{
fileList.add(new FileSubmitted(rs.getString("username"),
rs.getString("courseID"),
rs.getString("assignmentID"),
rs.getString("fileName"),
rs.getString("mimeType"),
(Blob) rs.getBlob("contents")));
}
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 (FileSubmitted file : fileList)
{
InputStream input = null;
try {
input = new BufferedInputStream(file.getContents().getBinaryStream(), DEFAULT_BUFFER_SIZE);
output.putNextEntry(new ZipEntry(file.getFileName()));
for (int length = 0; (length = input.read(buffer)) > 0;)
{
output.write(buffer, 0, length);
}
}//try
catch (SQLException e) {e.printStackTrace();}
finally{}
output.closeEntry();
}//for
}//try
finally{}
}
catch (Exception e1) {e1.printStackTrace();}
finally{}
}
采纳答案by Lani1234
In case this can be helpful to anyone else, I found the answer to the problem. The code posted above actually works perfectly for downloading multiple files from a database and creating a zip file for the client to download. The problem was that I was calling the servlet via ajax, and apparently you can't download files via an ajax call. So I changed my jsp page to call the servlet via submitting a form, and then the download came through to the browser perfectly.
如果这对其他人有帮助,我找到了问题的答案。上面发布的代码实际上非常适合从数据库下载多个文件并创建一个 zip 文件供客户端下载。问题是我通过ajax调用servlet,显然你不能通过ajax调用下载文件。所以我把我的jsp页面改成通过提交表单来调用servlet,然后下载到浏览器就完美了。
回答by Kiran Jujare
First create a zip file which contains all the zip files.
首先创建一个包含所有 zip 文件的 zip 文件。
Use ServletOutputStream
instead of ZipOutputStream
.
使用ServletOutputStream
代替ZipOutputStream
。
Then use the below code
然后使用下面的代码
protected void doGet(final HttpServletRequest request, final HttpServletResponse response) {
final String filename = "/usr/local/FileName" + ".zip";
BufferedInputStream buf = null;
ServletOutputStream myOut = null;
try {
myOut = response.getOutputStream();
File myfile = new File(filename);
if (myfile.exists()) {
//myfile.createNewFile();
//set response headers
response.setHeader("Cache-Control", "max-age=60");
response.setHeader("Cache-Control", "must-revalidate");
response.setContentType("application/zip");
response.addHeader("Content-Disposition", "attachment; filename=" + filename);
response.setContentLength((int) myfile.length());
FileInputStream input = new FileInputStream(myfile);
buf = new BufferedInputStream(input);
int readBytes = 0;
//read from the file; write to the ServletOutputStream
while ((readBytes = buf.read()) != -1) {
myOut.write(readBytes);
}
}
} catch (Exception exp) {
} finally {
//close the input/output streams
if (myOut != null) {
try {
myOut.close();
} catch (IOException ex) {
}
}
if (buf != null) {
try {
buf.close();
} catch (IOException ex) {
}
}
}
}