java—servlet實現檔案下載功能
阿新 • • 發佈:2019-02-12
最近在學javaweb技術,利用所學知識做了一個簡單的專案,在伺服器上實現給使用者下載檔案的功能。自動列出資料夾下的檔案提供下載,支援中文檔名。
結果圖
其中使用了tomcat來部署伺服器,程式碼中應用了少許EL表示式和JSTL標籤,使用了jsp和servlet,當然還有java和http的基礎知識,但是個人覺得重點是http的Content-Disposition頭資訊和Content-type頭資訊在servlet中下載方面的應用,詳見DownloadPageServlet.java原始碼。
講解的比較詳細,但是程式碼貌似不是java的。
關於Content-type,可以參考線上工具:
本專案包含一個jsp檔案,用來展示可下載的檔案列表,顯示為超連結,使用者點選即可下載對應檔案。一個javabean,用來儲存可供使用者下載的檔案和檔名。一個servlet,用來提供下載功能。
Jsp中超連結的實現方式:指向servlet,在網址後面附加引數,servlet可以根據附加引數知道使用者想要下載哪個檔案。
結構圖
備註1.本人覺得專案結構並不是很好,還望指教。
2.不知道有沒有方便的專用作圖軟體。
如果讀者對上面2個問題有所瞭解的話還望指導。
在myeclipse中新建一個web程式,新增下述3個檔案,修改一下包名錯誤,在web.xml中配飾上servlet,訪問jsp檔案,應該就可以看到效果了。
DownloadPageServlet.java原始碼
package com.ima.downLoad; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.net.URLEncoder; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.ima.downLoad.util.FilesBean; public class DownloadPageServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); //理論上傳來的網址是 ?後面跟一個數字表示第n個檔案 String str = request.getQueryString(); //如果沒有引數則什麼也不做 if (str != null) { FilesBean bean = new FilesBean(); File f = null; try { f = bean.getFiles().get(Integer.valueOf(str) - 1); } catch (Exception e) { // 沒有對應檔案會丟擲陣列越界異常 e.printStackTrace(); return; } System.out.println("DownloadPageServlet:使用者欲得到的資源是 " + f.getName()); if (f != null) { BufferedInputStream bis = null; try { // 得到檔案輸入流 bis = new BufferedInputStream(new FileInputStream(f)); // !!! //設定http頭資訊為檔案下載 //!!!保證在下一步之前,我曾經寫在下一步之後,不能正常實現功能 response.setContentType("application/octet-stream"); response.addHeader( "Content-Disposition", "attachment;filename=" + URLEncoder.encode(f.getName(), "UTF-8")); // 得到應答輸出流,並寫入 ServletOutputStream os = response.getOutputStream(); byte[] buf = new byte[1024 * 8]; int len = -1; while ((len = bis.read(buf)) != -1) { os.write(buf, 0, len); } } catch (Exception e) { } finally { if (bis != null) bis.close(); } } } } }
FileBean.java原始碼
package com.ima.downLoad.util;
import java.io.File;
import java.util.ArrayList;
/**
* 獲得指定資料夾下的檔案,生成list,對外提供檔案list和檔名list
* @author tor
*
*/
public class FilesBean {
private String targetDir = "E:/imaLearn/8組共享/";
//下面2個list應該是同步的
//檔案list,用來讀取
ArrayList<File> files = new ArrayList<File>();
//檔名list,用來顯示
ArrayList<String> fileNames = new ArrayList<String>();
public FilesBean() {
init();
}
public ArrayList<String> getFileNames() {
return fileNames;
}
/**
* 初始化函式,每次改變相關引數需要呼叫
*/
private void init() {
File[] fileList = new File(targetDir).listFiles();
for (File file : fileList) {
if (file.canRead() && file.canWrite() && !file.isHidden()) {
files.add(file);
fileNames.add(file.getName());
}
}
}
public String getTargetDir() {
return targetDir;
}
public void setTargetDir(String targetDir) {
this.targetDir = targetDir;
init();//重新初始化
}
public ArrayList<File> getFiles() {
return files;
}
}
showFiles.jsp原始碼
<%@page import="com.ima.downLoad.util.FilesBean"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>下載資源頁面</title>
</head>
<body>
<h3>8組共享</h3><br/>
<%request.setAttribute("fileBean", new FilesBean()); %>
<c:forEach items="${fileBean.fileNames }" var="file" varStatus="state">
<a target="_blank" href="${pageContext.request.contextPath }/servlet/DownloadPageServlet?${state.count }">${file }</a><br/>
</c:forEach>
</body>
</html>