Apache 文件上傳與文件下載案例詳解
寫一個(gè)Apache文件上傳與文件下載的案例:以供今后學(xué)習(xí)
web.xml配置如下:
<span style="font-family:SimSun;font-size:14px;"><?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<display-name>FileUploadAndDownload</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<!-- 上傳配置 -->
<servlet>
<servlet-name>uploadHandleServlet</servlet-name>
<servlet-class>com.zeng.controller.UploadHandleServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>uploadHandleServlet</servlet-name>
<url-pattern>/upload/uploadHandleServlet</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>listFileServlet</servlet-name>
<servlet-class>com.zeng.controller.ListFileServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>listFileServlet</servlet-name>
<url-pattern>/listFileServlet</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>downLoadServlet</servlet-name>
<servlet-class>com.zeng.controller.DownLoadServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>downLoadServlet</servlet-name>
<url-pattern>/download/downLoadServlet</url-pattern>
</servlet-mapping>
</web-app></span>
2.upload.jsp文件
<span style="font-family:SimSun;font-size:14px;"><%@page language="java" pageEncoding="UTF-8"%>
<!DOCTYPE HTML>
<html>
<head>
<title>文件上傳</title>
</head>
<body>
<!--
${pageContext.request.contextPath} : 作用是取出部署的應(yīng)用程序名
缺點(diǎn):操作不便,其他工具無法正確解釋${pageContext.request.contextPath}
如果Servlet的配置路徑為 /upload/uploadHandleServlet
action跳轉(zhuǎn)路徑為: ${pageContext.request.contextPath}/upload/uploadHandleServlet
上傳文件時(shí),必須
1.enctype="multipart/form-data"
2.method=post
-->
<form action="${pageContext.request.contextPath}/upload/uploadHandleServlet" enctype="multipart/form-data" method="post">
上傳用戶:<input type="text" name="username"><br/>
上傳文件1:<input type="file" name="file1"><br/>
上傳文件2:<input type="file" name="file2"><br/>
<input type="submit" value="提交">
</form>
</body>
</html></span>
3.message.jsp
<span style="font-family:SimSun;font-size:14px;"><%@page language="java" pageEncoding="UTF-8"%>
<!DOCTYPE HTML>
<html>
<head>
<title>消息提示</title>
</head>
<body>
${message}
</body>
</html></span>
4.UploadHandleServlet.java
<span style="font-family:SimSun;font-size:14px;">package com.zeng.controller;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.UUID;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadBase;
import org.apache.commons.fileupload.ProgressListener;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
/**
* @ClassName: UploadHandleServlet
* @Description: TODO(這里用一句話描述這個(gè)類的作用)
*/
public class UploadHandleServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//得到上傳文件的保存目錄,將上傳的文件存放于WEB-INF目錄下,不允許外界直接訪問,保證上傳文件的安全
String savePath = this.getServletContext().getRealPath("/WEB-INF/upload");
//上傳時(shí)生成的臨時(shí)文件保存目錄
String tempPath = this.getServletContext().getRealPath("/WEB-INF/temp");
File tmpFile = new File(tempPath);
if (!tmpFile.exists()) {
//創(chuàng)建臨時(shí)目錄
tmpFile.mkdir();
}
//消息提示
String message = "";
try{
//使用Apache文件上傳組件處理文件上傳步驟:
//1、創(chuàng)建一個(gè)DiskFileItemFactory工廠
DiskFileItemFactory factory = new DiskFileItemFactory();
//設(shè)置工廠的緩沖區(qū)的大小,當(dāng)上傳的文件大小超過緩沖區(qū)的大小時(shí),就會生成一個(gè)臨時(shí)文件存放到指定的臨時(shí)目錄當(dāng)中。
factory.setSizeThreshold(1024*100);//設(shè)置緩沖區(qū)的大小為100KB,如果不指定,那么緩沖區(qū)的大小默認(rèn)是10KB
//設(shè)置上傳時(shí)生成的臨時(shí)文件的保存目錄
factory.setRepository(tmpFile);
//2、創(chuàng)建一個(gè)文件上傳解析器
ServletFileUpload upload = new ServletFileUpload(factory);
//監(jiān)聽文件上傳進(jìn)度
upload.setProgressListener(new ProgressListener(){
public void update(long pBytesRead, long pContentLength, int arg2) {
System.out.println("文件大小為:" + pContentLength + ",當(dāng)前已處理:" + pBytesRead + ",arg2: " + arg2);
/**
* 文件大小為:14608,當(dāng)前已處理:4096
文件大小為:14608,當(dāng)前已處理:7367
文件大小為:14608,當(dāng)前已處理:11419
文件大小為:14608,當(dāng)前已處理:14608
*/
}
});
//解決上傳文件名的中文亂碼
upload.setHeaderEncoding("UTF-8");
//3、判斷提交上來的數(shù)據(jù)是否是上傳表單的數(shù)據(jù)
if(!ServletFileUpload.isMultipartContent(request)){
//按照傳統(tǒng)方式獲取數(shù)據(jù)
return;
}
//設(shè)置上傳單個(gè)文件的大小的最大值,目前是設(shè)置為1024*1024*20字節(jié),也就是20MB
upload.setFileSizeMax(1024*1024*20);
//設(shè)置上傳文件總量的最大值,最大值=同時(shí)上傳的多個(gè)文件的大小的最大值的和,目前設(shè)置為100MB
upload.setSizeMax(1024*1024*100);
//4、使用ServletFileUpload解析器解析上傳數(shù)據(jù),解析結(jié)果返回的是一個(gè)List<FileItem>集合,每一個(gè)FileItem對應(yīng)一個(gè)Form表單的輸入項(xiàng)
List<FileItem> list = upload.parseRequest(request);
for(FileItem item : list){
//如果fileitem中封裝的是普通輸入項(xiàng)的數(shù)據(jù)
if(item.isFormField()){
String name = item.getFieldName();
//解決普通輸入項(xiàng)的數(shù)據(jù)的中文亂碼問題
String value = item.getString("UTF-8");
System.out.println(name + "=" + value);
}else{//如果fileitem中封裝的是上傳文件
//得到上傳的文件名稱,
String filename = item.getName();
System.out.println(filename);
if(filename==null || filename.trim().equals("")){
continue;
}
//注意:不同的瀏覽器提交的文件名是不一樣的,有些瀏覽器提交上來的文件名是帶有路徑的,如: c:\a\b\1.txt,而有些只是單純的文件名,如:1.txt
//處理獲取到的上傳文件的文件名的路徑部分,只保留文件名部分
filename = filename.substring(filename.lastIndexOf("\\")+1);
//得到上傳文件的擴(kuò)展名
String fileExtName = filename.substring(filename.lastIndexOf(".")+1);
//如果需要限制上傳的文件類型,那么可以通過文件的擴(kuò)展名來判斷上傳的文件類型是否合法
System.out.println("上傳的文件的擴(kuò)展名是:"+fileExtName);
//獲取item中的上傳文件的輸入流
InputStream in = item.getInputStream();
//得到文件保存的名稱
String saveFilename = makeFileName(filename);
//文件名:d507ef2e-aca9-4908-a8b9-c1d1c6a2f4d9_日語二級語法大全(推薦).doc
//System.out.println("saveFilename: " + saveFilename);
//得到文件的保存目錄
String realSavePath = makePath(saveFilename, savePath);
//創(chuàng)建一個(gè)文件輸出流
FileOutputStream out = new FileOutputStream(realSavePath + "\\" + saveFilename);
//創(chuàng)建一個(gè)緩沖區(qū)
byte buffer[] = new byte[1024];
//判斷輸入流中的數(shù)據(jù)是否已經(jīng)讀完的標(biāo)識
int len = 0;
//循環(huán)將輸入流讀入到緩沖區(qū)當(dāng)中,(len=in.read(buffer))>0就表示in里面還有數(shù)據(jù)
while((len=in.read(buffer))>0){
//使用FileOutputStream輸出流將緩沖區(qū)的數(shù)據(jù)寫入到指定的目錄(savePath + "\\" + filename)當(dāng)中
out.write(buffer, 0, len);
}
//關(guān)閉輸入流
in.close();
//關(guān)閉輸出流
out.close();
//刪除處理文件上傳時(shí)生成的臨時(shí)文件
//item.delete();
message = "文件上傳成功!";
}
}
}catch (FileUploadBase.FileSizeLimitExceededException e) {
e.printStackTrace();
request.setAttribute("message", "單個(gè)文件超出最大值?。?!");
request.getRequestDispatcher("../message.jsp").forward(request, response);
return;
}catch (FileUploadBase.SizeLimitExceededException e) {
e.printStackTrace();
request.setAttribute("message", "上傳文件的總的大小超出限制的最大值!??!");
request.getRequestDispatcher("../message.jsp").forward(request, response);
return;
}catch (Exception e) {
message= "文件上傳失敗!";
e.printStackTrace();
}
request.setAttribute("message",message);
//訪問路徑 /FileUploadAndDownload/upload/upload.jsp
//跳轉(zhuǎn)路徑 /FileUploadAndDownload/upload/listFileServlet
//轉(zhuǎn)發(fā)路徑 /FileUploadAndDownload/message.jsp
//當(dāng)前路徑是在/FileUploadAndDownload/upload/下,要跳到/FileUploadAndDownload/下,必須../message.jsp
//-----如果 message.jsp是在/FileUploadAndDownload/upload/下,則直接使用message.jsp
request.getRequestDispatcher("../message.jsp").forward(request, response);
}
/**
* @Method: makeFileName
* @Description: 生成上傳文件的文件名,文件名以:uuid+"_"+文件的原始名稱
* @param filename 文件的原始名稱
* @return uuid+"_"+文件的原始名稱
*/
private String makeFileName(String filename){ //2.jpg
//為防止文件覆蓋的現(xiàn)象發(fā)生,要為上傳文件產(chǎn)生一個(gè)唯一的文件名
return UUID.randomUUID().toString() + "_" + filename;
}
/**
* 為防止一個(gè)目錄下面出現(xiàn)太多文件,要使用hash算法打散存儲
* @Method: makePath
* @param filename 文件名,要根據(jù)文件名生成存儲目錄
* @param savePath 文件存儲路徑
* @return 新的存儲目錄
*/
private String makePath(String filename,String savePath){
//得到文件名的hashCode的值,得到的就是filename這個(gè)字符串對象在內(nèi)存中的地址
int hashcode = filename.hashCode();
int dir1 = hashcode&0xf; //0--15
int dir2 = (hashcode&0xf0)>>4; //0-15
//構(gòu)造新的保存目錄
String dir = savePath + "\\" + dir1 + "\\" + dir2; //upload\2\3 upload\3\5
//hashcode: -1390239557 dir1: 11 dir: 11 (以d507ef2e-aca9-4908-a8b9-c1d1c6a2f4d9_日語二級語法大全(推薦).doc為例子)
System.out.println("上傳前:hashcode: "+ hashcode + " dir1: " +dir1 + " dir: " + dir2);
//File既可以代表文件也可以代表目錄
File file = new File(dir);
//如果目錄不存在
if(!file.exists()){
//創(chuàng)建目錄
file.mkdirs();
}
return dir;
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
// ----------------------------------------------------------簡單版本,不處理上傳空間和上傳的文件名
//
//import java.io.File;
//import java.io.FileOutputStream;
//import java.io.IOException;
//import java.io.InputStream;
//import java.util.List;
//import javax.servlet.ServletException;
//import javax.servlet.http.HttpServlet;
//import javax.servlet.http.HttpServletRequest;
//import javax.servlet.http.HttpServletResponse;
//import org.apache.commons.fileupload.FileItem;
//import org.apache.commons.fileupload.disk.DiskFileItemFactory;
//import org.apache.commons.fileupload.servlet.ServletFileUpload;
//
//public class UploadHandleServlet extends HttpServlet {
//
// public void doGet(HttpServletRequest request, HttpServletResponse response)
// throws ServletException, IOException {
// //得到上傳文件的保存目錄,將上傳的文件存放于WEB-INF目錄下,不允許外界直接訪問,保證上傳文件的安全
// String savePath = this.getServletContext().getRealPath("/WEB-INF/upload");
// File file = new File(savePath);
// //判斷上傳文件的保存目錄是否存在
// if (!file.exists() && !file.isDirectory()) {
// System.out.println(savePath+"目錄不存在,需要創(chuàng)建");
// //創(chuàng)建目錄
// file.mkdir();
// }
// //消息提示
// String message = "";
// try{
// //使用Apache文件上傳組件處理文件上傳步驟:
// //1、創(chuàng)建一個(gè)DiskFileItemFactory工廠
// DiskFileItemFactory factory = new DiskFileItemFactory();
// //2、創(chuàng)建一個(gè)文件上傳解析器
// ServletFileUpload upload = new ServletFileUpload(factory);
// //解決上傳文件名的中文亂碼
// upload.setHeaderEncoding("UTF-8");
// //3、判斷提交上來的數(shù)據(jù)是否是上傳表單的數(shù)據(jù)
// if(!ServletFileUpload.isMultipartContent(request)){
// //按照傳統(tǒng)方式獲取數(shù)據(jù)
// return;
// }
// //4、使用ServletFileUpload解析器解析上傳數(shù)據(jù),解析結(jié)果返回的是一個(gè)List<FileItem>集合,每一個(gè)FileItem對應(yīng)一個(gè)Form表單的輸入項(xiàng)
// List<FileItem> list = upload.parseRequest(request);
// for(FileItem item : list){
// //如果fileitem中封裝的是普通輸入項(xiàng)的數(shù)據(jù)
// if(item.isFormField()){
// String name = item.getFieldName();
// //解決普通輸入項(xiàng)的數(shù)據(jù)的中文亂碼問題
// String value = item.getString("UTF-8");
// //value = new String(value.getBytes("iso8859-1"),"UTF-8");
// System.out.println(name + "=" + value);
// }else{//如果fileitem中封裝的是上傳文件
// //得到上傳的文件名稱,
// String filename = item.getName();
// System.out.println(filename);
// if(filename==null || filename.trim().equals("")){
// continue;
// }
// //注意:不同的瀏覽器提交的文件名是不一樣的,有些瀏覽器提交上來的文件名是帶有路徑的,如: c:\a\b\1.txt,而有些只是單純的文件名,如:1.txt
// //處理獲取到的上傳文件的文件名的路徑部分,只保留文件名部分
// filename = filename.substring(filename.lastIndexOf("\\")+1);
// //獲取item中的上傳文件的輸入流
// InputStream in = item.getInputStream();
// //創(chuàng)建一個(gè)文件輸出流
// FileOutputStream out = new FileOutputStream(savePath + "\\" + filename);
// //創(chuàng)建一個(gè)緩沖區(qū)
// byte buffer[] = new byte[1024];
// //判斷輸入流中的數(shù)據(jù)是否已經(jīng)讀完的標(biāo)識
// int len = 0;
// //循環(huán)將輸入流讀入到緩沖區(qū)當(dāng)中,(len=in.read(buffer))>0就表示in里面還有數(shù)據(jù)
// while((len=in.read(buffer))>0){
// //使用FileOutputStream輸出流將緩沖區(qū)的數(shù)據(jù)寫入到指定的目錄(savePath + "\\" + filename)當(dāng)中
// out.write(buffer, 0, len);
// }
// //關(guān)閉輸入流
// in.close();
// //關(guān)閉輸出流
// out.close();
// //刪除處理文件上傳時(shí)生成的臨時(shí)文件
// item.delete();
// message = "文件上傳成功!";
// }
// }
// }catch (Exception e) {
// message= "文件上傳失??!";
// e.printStackTrace();
//
// }
// request.setAttribute("message",message);
// request.getRequestDispatcher("/message.jsp").forward(request, response);
// }
//
// public void doPost(HttpServletRequest request, HttpServletResponse response)
// throws ServletException, IOException {
//
// doGet(request, response);
// }
//}</span>
<上傳文件完畢>
1.listfile.jsp
<span style="font-family:SimSun;font-size:14px;"><%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE HTML>
<html>
<head>
<title>下載文件顯示頁面</title>
<meta charset="UTF-8">
<style type="text/css">
.filelistTab{
width: 500px;
border: 2px solid gray;
border-collapse: collapse;
}
.filelistTd{
height:25px;
border: 1px solid gray;
}
</style>
</head>
<body>
<%--
<c:url var="path" value="download/downLoadServlet">
<c:param name="filename" value="myOPQ"></c:param>
</c:url>
<a href="${path }" rel="external nofollow" rel="external nofollow" >下載文件</a>
--%>
<!-- 遍歷Map集合 -->
<table class="filelistTab">
<c:forEach items="${fileNameMap }" var="fileNames">
<tr>
<td class="filelistTd">
<c:url value="download/downLoadServlet" var="path">
<c:param name="filename" value="${fileNames.key}"></c:param>
</c:url>${fileNames.value}
</td>
<td class="filelistTd"><a href="${path }" rel="external nofollow" rel="external nofollow" >下載</a></td>
</tr>
</c:forEach>
</table>
</body>
</html></span>
2.ListFileServlet.java
<span style="font-family:SimSun;font-size:14px;">package com.zeng.controller;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @ClassName: ListFileServlet
* @Description: 列出Web系統(tǒng)中所有下載文件
*/
public class ListFileServlet extends HttpServlet {
/*
* ListFileServlet中l(wèi)istfile方法,listfile方法是用來列出目錄下的所有文件的,
* listfile方法內(nèi)部用到了遞歸,在實(shí)際開發(fā)當(dāng)中,我們肯定會在數(shù)據(jù)庫創(chuàng)建一張表,
* 里面會存儲上傳的文件名以及文件的具體存放目錄,我們通過查詢表就可以知道文件的具體存放目錄,
* 是不需要用到遞歸操作的,這個(gè)例子是因?yàn)闆]有使用數(shù)據(jù)庫存儲上傳的文件名和文件的具體存放位置,
* 而上傳文件的存放位置又使用了散列算法打散存放,所以需要用到遞歸,在遞歸時(shí),
* 將獲取到的文件名存放到從外面?zhèn)鬟f到listfile方法里面的Map集合當(dāng)中,
* 這樣就可以保證所有的文件都存放在同一個(gè)Map集合當(dāng)中。
* */
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//獲取上傳文件的目錄
String uploadFilePath = this.getServletContext().getRealPath("/WEB-INF/upload");
//存儲要下載的文件名
Map<String,String> fileNameMap = new HashMap<String,String>();
//
File file = new File(uploadFilePath);
if(!file.exists()){
//如果文件路徑不存在,則轉(zhuǎn)發(fā)
request.setAttribute("message", "路徑為空路徑");
request.getRequestDispatcher("message.jsp").forward(request, response);
}else{
//如果文件路徑存在,則進(jìn)行遍歷所有文件
//遞歸遍歷filepath目錄下的所有文件和目錄,將文件的文件名存儲到map集合中
listfile(file,fileNameMap);//File既可以代表一個(gè)文件也可以代表一個(gè)目錄
//將Map集合發(fā)送到listfile.jsp頁面進(jìn)行顯示
request.setAttribute("fileNameMap", fileNameMap);
request.getRequestDispatcher("listfile.jsp").forward(request, response);
}
}
/**
* @Method: listfile
* @Description: 遞歸遍歷指定目錄下的所有文件
* @param file 即代表一個(gè)文件,也代表一個(gè)文件目錄
* @param map 存儲文件名的Map集合
*/
public void listfile(File file,Map<String,String> map){
//如果file代表的不是一個(gè)文件,而是一個(gè)目錄
if(!file.isFile()){
//列出該目錄下的所有文件和目錄
File files[] = file.listFiles();
//遍歷files[]數(shù)組
for(File f : files){
//遞歸
listfile(f,map);
}
}else{
/**
* 處理文件名,上傳后的文件是以uuid_文件名的形式去重新命名的,去除文件名的uuid_部分
file.getName().indexOf("_")檢索字符串中第一次出現(xiàn)"_"字符的位置,如果文件名類似于:9349249849-88343-8344_阿_凡_達(dá).avi
那么file.getName().substring(file.getName().indexOf("_")+1)處理之后就可以得到阿_凡_達(dá).avi部分
*/
String realName = file.getName().substring(file.getName().indexOf("_")+1);
//file.getName()得到的是文件的原始名稱,這個(gè)名稱是唯一的,因此可以作為key,realName是處理過后的名稱,有可能會重復(fù)
map.put(file.getName(), realName);
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}</span>
<展示完畢>
1.DownLoadServlet.Java
<span style="font-family:SimSun;font-size:14px;">package com.zeng.controller;
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 {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("進(jìn)入");
/*
* fileName的格式:文件名以:uuid+"_"+文件的原始名稱
* 得到fileName:d507ef2e-aca9-4908-a8b9-c1d1c6a2f4d9_日語二級語法大全(推薦).doc
*
* listfile.jsp的路徑傳遞是以 download/downLoadServlet提交
*
* 路徑內(nèi)容為:
* /FileUploadAndDownload/download/downLoadServlet
* ?filename=d507ef2e-aca9-4908-a8b9-c1d1c6a2f4d9_日語二級語法大全(推薦).doc
* */
String fileName = request.getParameter("filename");
// 注意:使用了下面一句字符轉(zhuǎn)碼時(shí),出錯(cuò):打不到文件,
//dir1和dir2的數(shù)字前后各不相同,導(dǎo)致重新創(chuàng)建了文件,而文件內(nèi)又沒有文件,故報(bào)找不到文件錯(cuò)誤
//fileName = new String(fileName.getBytes("iso8859-1"),"UTF-8");
System.out.println("fileName: " + fileName);
//上傳的文件都是保存在/WEB-INF/upload目錄下的子目錄當(dāng)中
String fileSaveRootPath=this.getServletContext().getRealPath("/WEB-INF/upload");
System.out.println("fileSaveRootPath: "+ fileSaveRootPath);
//通過文件名找出文件的所在目錄
String path = findFileSavePathByFileName(fileName,fileSaveRootPath);
System.out.println("path: "+ path);
//服務(wù)器安裝位置\wtpwebapps\FileUploadAndDownload\WEB-INF\ upload\11\11
//得到要下載的文件,文件類型是 : uuid + "_" + 文件名
File file = new File(path + "\\" + fileName);
System.out.println("file: "+ file.getAbsolutePath());
//如果文件不存在
if(!file.exists()){
request.setAttribute("message", "您要下載的資源已被刪除??!");
//轉(zhuǎn)發(fā)到錯(cuò)誤頁面,此處要注意路徑問題
request.getRequestDispatcher("../message.jsp").forward(request, response);
return;
}
//處理文件名,得到去除uuid后的文件名
String realname = fileName.substring(fileName.indexOf("_")+1);
System.out.println("realname: "+ realname);
/*
* 文件下載
* 設(shè)置content-disposition響應(yīng)頭控制瀏覽器以下載的形式打開文件
* 下載中文文件時(shí),需要注意的地方就是中文文件名要使用
* URLEncoder.encode()方法進(jìn)行編碼(URLEncoder.encode(fileName, "字符編碼")),
* 否則會出現(xiàn)文件名亂碼。
* */
response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(realname, "UTF-8"));
//讀取要下載的文件,保存到文件輸入流,此處的路徑還是帶有uuid
FileInputStream in = new FileInputStream(path + "\\" + fileName);
//創(chuàng)建輸出流
OutputStream out = response.getOutputStream();
//創(chuàng)建緩沖區(qū)
byte buffer[] = new byte[1024];
int len = 0;
//循環(huán)將輸入流中的內(nèi)容讀取到緩沖區(qū)當(dāng)中
while((len=in.read(buffer))>0){
//輸出緩沖區(qū)的內(nèi)容到瀏覽器,實(shí)現(xiàn)文件下載
out.write(buffer, 0, len);
}
//關(guān)閉文件輸入流
in.close();
//關(guān)閉輸出流
out.close();
}
/**
* @Method: findFileSavePathByFileName
* @Description: 通過文件名和存儲上傳文件根目錄找出要下載的文件的所在路徑
* @param filename 要下載的文件名
* @param saveRootPath 上傳文件保存的根目錄,也就是/WEB-INF/upload目錄
* @return 要下載的文件的存儲目錄
*/
public String findFileSavePathByFileName(String filename,String saveRootPath){
int hashcode = filename.hashCode();
int dir1 = hashcode&0xf; //0--15
int dir2 = (hashcode&0xf0)>>4; //0-15
String dir = saveRootPath + "\\" + dir1 + "\\" + dir2; //upload\2\3 upload\3\5
//hashcode: -1390239557 dir1: 11 dir: 11 (以d507ef2e-aca9-4908-a8b9-c1d1c6a2f4d9_日語二級語法大全(推薦).doc為例子)
System.out.println("hashcode: "+ hashcode + " dir1: " +dir1 + " dir: " + dir2);
File file = new File(dir);
if(!file.exists()){
//創(chuàng)建目錄
file.mkdirs();
}
return dir;
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}</span>
以上所述是小編給大家介紹的Apache 文件上傳與文件下載案例詳解,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時(shí)回復(fù)大家的。在此也非常感謝大家對本站網(wǎng)站的支持!
版權(quán)聲明:本站文章來源標(biāo)注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請保持原文完整并注明來源及原文鏈接。禁止復(fù)制或仿造本網(wǎng)站,禁止在非maisonbaluchon.cn所屬的服務(wù)器上建立鏡像,否則將依法追究法律責(zé)任。本站部分內(nèi)容來源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來,僅供學(xué)習(xí)參考,不代表本站立場,如有內(nèi)容涉嫌侵權(quán),請聯(lián)系alex-e#qq.com處理。
關(guān)注官方微信