● 列出提供下載的文件資源html
咱們要將Web應用系統中的文件資源提供給用戶進行下載,首先咱們要有一個頁面列出上傳文件目錄下的全部文件,當用戶點擊文件下載超連接時就進行下載操做,編寫一個ListFileServlet,用於列出Web應用系統中全部下載文件。java
ListFileServlet的代碼以下:web
package com.xdl.servlet;算法
import java.io.File;數據庫
import java.io.IOException;數組
import java.util.HashMap;瀏覽器
import java.util.Map;app
import javax.servlet.ServletException;jsp
import javax.servlet.http.HttpServlet;ui
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ListFileServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public void service(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// 獲取上傳文件的目錄
String uploadFilePath = this.getServletContext().
getRealPath("/WEB-INF/ upload");
// 存儲要下載的文件名
Map<String, String> fileNameMap = new HashMap<String, String>();
// 遞歸遍歷filepath目錄下的全部文件和目錄,將文件的文件名存儲到map集合中
listfile(new File(uploadFilePath), fileNameMap);
// File既能夠表明一個文件也能夠表明一個目錄
// 將Map集合發送到listfile.jsp頁面進行顯示
request.setAttribute("fileNameMap", fileNameMap);
request.getRequestDispatcher("/listfile.jsp").
forward(request, response);
}
public void listfile(File file, Map<String, String> map) {
// 若是file表明的不是一個文件,而是一個目錄
if (!file.isFile()) {
// 列出該目錄下的全部文件和目錄
File files[] = file.listFiles();
// 遍歷files[]數組
for (File f : files) {
// 遞歸
listfile(f, map);
}
} else {
/**
* 處理文件名,上傳後的文件是以uuid_文件名的形式去從新命名的
*/
String realName = file.getName().substring(
file.getName().indexOf ("_") + 1);
// file.getName()獲得的是文件的原始名稱,這個名稱是惟一的,
// 所以能夠做爲key,realName是處理事後的名稱,有可能會重複
map.put(file.getName(), realName);
}
}
}
這裏介紹一下ListFileServlet中listfile方法,listfile方法是用來列出目錄下的全部文件的,listfile方法內部用到了遞歸,在實際開發當中,咱們確定會在數據庫建立一張表,裏面會存儲上傳的文件名以及文件的具體存放目錄,咱們經過查詢表就能夠知道文件的具體存放目錄,是不須要用到遞歸操做的,這個例子是由於沒有使用數據庫存儲上傳的文件名和文件的具體存放位置,而上傳文件的存放位置又使用了散列算法打散存放,因此須要用到遞歸,在遞歸時,將獲取到的文件名存放到從外面傳遞到listfile方法裏面的Map集合當中,這樣就能夠保證全部的文件都存放在同一個Map集合當中。
在web.xml文件中配置ListFileServlet。
<servlet>
<servlet-name>ListFileServlet</servlet-name>
<servlet-class>com.xdl.servlet.ListFileServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ListFileServlet</servlet-name>
<url-pattern>/list</url-pattern>
</servlet-mapping>
● 展現下載文件的listfile.jsp頁面,代碼以下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>兄弟連IT教育</title>
</head>
<body>
<c:forEach var="me" items="${fileNameMap}">
<c:url value="/download" var="downurl">
<c:param name="filename" value="${me.key}"></c:param>
</c:url>
${me.value}<a href="${downurl}">下載</a>
<br />
</c:forEach>
</body>
</html>
訪問ListFileServlet,就能夠在listfile.jsp頁面中顯示提供給用戶下載的文件資源,如圖25所示。
圖25 listfile.jsp頁面
● 實現文件下載
編寫一個用於處理文件下載的Servlet,DownloadServlet的代碼以下:
package com.xdl.servlet;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class DownloadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public void service(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// 獲得要下載的文件名
String fileName = request.getParameter("filename");
// 上傳的文件都是保存在/WEB-INF/upload目錄下的子目錄當中
String fileSaveRootPath =
this.getServletContext().getRealPath ("/WEB-INF/upload");
// 經過文件名找出文件的所在目錄
String path = findFileSavePathByFileName(fileName, fileSaveRootPath);
// 獲得要下載的文件
File file = new File(path + "\\" + fileName);
// 若是文件不存在
if (!file.exists()) {
request.setAttribute("message", "您要下載的資源已被刪除!!");
request.getRequestDispatcher("/message.jsp").
forward(request, response);
return;
}
// 處理文件名
String realname = fileName.substring(fileName.indexOf("_") + 1);
// 設置響應頭,控制瀏覽器下載該文件
response.setHeader("content-disposition",
"attachment;filename=" + URLEncoder.
encode(realname, "UTF-8"));
// 讀取要下載的文件,保存到文件輸入流
FileInputStream in = new FileInputStream(path + "\\" + fileName);
// 建立輸出流
OutputStream out = response.getOutputStream();
// 建立緩衝區
byte buffer[] = new byte[1024];
int len = 0;
// 循環將輸入流中的內容讀取到緩衝區當中
while ((len = in.read(buffer)) > 0) {
// 輸出緩衝區的內容到瀏覽器,實現文件下載
out.write(buffer, 0, len);
}
// 關閉文件輸入流
in.close();
// 關閉輸出流
out.close();
}
public String findFileSavePathByFileName
(String filename, String saveRootPath) {
int hashcode = filename.hashCode();
int dir1 = hashcode & 0xf;
int dir2 = (hashcode & 0xf0) >> 4;
String dir = saveRootPath + "\\" + dir1 + "\\" + dir2;
File file = new File(dir);
if (!file.exists()) {
// 建立目錄
file.mkdirs();
}
return dir;
}
}
● 在web.xml文件中配置DownloadServlet。
<servlet>
<servlet-name>DownloadServlet</servlet-name>
<servlet-class>com.xdl.servlet.DownloadServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DownloadServlet</servlet-name>
<url-pattern>/download</url-pattern>
</servlet-mapping>
再次訪問ListFileServlet,就能夠在listfile.jsp頁面中點擊下載開始下載資源,如圖26所示。
圖26 下載文件
圖27 下載文件成功
從運行結果能夠看到,咱們的文件下載功能已經能夠正常下載文件了。