servlet實(shí)現(xiàn)文件上傳與下載功能
本文實(shí)例為大家分享了servlet實(shí)現(xiàn)文件上傳與下載的具體代碼,供大家參考,具體內(nèi)容如下
內(nèi)容
我們分兩大模塊來進(jìn)行講解,即上傳的實(shí)現(xiàn),與下載的實(shí)現(xiàn)
上傳的實(shí)現(xiàn)
注意了我們在寫上傳表單的時候必須聲明提交方式為post類型,enctype="multipart/form-data",這樣的話才能實(shí)現(xiàn)上傳。
當(dāng)我們提交表單的時候看看響應(yīng)體中都有什么內(nèi)容:

好了,我們有了數(shù)據(jù)了,接下來我們怎么提取數(shù)據(jù)呢,注意我們已經(jīng)不能使用requeest.getParamter()方法來進(jìn)行參數(shù)的提取了,那怎么辦呢,我們總不能自己寫實(shí)現(xiàn)類來進(jìn)行分割吧!我們可以使用Commons提供的小工具。
好了,讓我們來看看具體的操作步驟吧!這里我就不詳細(xì)說了,一文代碼流過:
/**
* 需要解決的問題:
* 1 必須要把文件存放到WEB-INF目錄下,避免用戶看到
* 2 文件名相關(guān)問題
* 1 有的瀏覽器會傳遞絕對路徑到name中,我們只需要進(jìn)行拆分即可
* 2文件重名問題,我們可以使用uuid
* 3文件名亂碼問題,我們已經(jīng)解決了。即request.setCharacterEncoding("utf-8");
* 3 文件打散問題
* 1通過首字符打散
* 2通過時間打散
* 3通過hash打散
* 4上傳文件大小限制
* 1單個文件上傳大小限制
* 2總文件上傳大小限制
* 設(shè)置這兩個參數(shù)時,我們必須在沒有解析之前執(zhí)行。
* 5 緩存大小與臨時目錄
*
*
*
**/
public class FileUploadServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
/**
* 我們使用commmons的小工具來進(jìn)行編碼
* 設(shè)置jsp頁面的enctype= “multipart/form-data“;
* 1 創(chuàng)建FileItem工廠
* 2創(chuàng)建ServletFileUpload對象
* 3 解析request得到FileItem
* 4對FileItem進(jìn)行操作
**/
String path = request.getSession().getServletContext().getRealPath("/WEB-INF");
//解決緩存大小,要不然你的內(nèi)存會爆的。
DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory(1024 * 10,new File(path + "/" + "tmp2") );
ServletFileUpload fileUpload = new ServletFileUpload(diskFileItemFactory);
List<FileItem> l = null;
try {
l = fileUpload.parseRequest(request);
FileItem f2 = l.get(0);
//解決文件存放在WEN_INF目錄下問題
path = path + "/tmp";
//解決瀏覽器傳遞絕對路徑問題
String name = f2.getName();
int i = name.lastIndexOf("/");
if(i != -1) {
name = name.substring(i);
}
//解決文件重名問題
name = (UUID.randomUUID().toString().replace("-","").trim()) + name;
//文件打散問題解決方法演示之hash打散
int has = name.hashCode();
//轉(zhuǎn)換位16進(jìn)制位,我們使用前兩個值來判斷
String hex = Integer.toHexString(has);
path = path + "/" + hex.charAt(0) + "/" + hex.charAt(2) ;
File file = new File(path);
if(! file.exists()) {
file.mkdirs();
}
f2.write(new File(path + "/" + name));
request.setAttribute("msg","恭喜你,上傳成功了!");
request.getRequestDispatcher("/index.jsp").forward(request, response);
} catch (Exception e) {
request.setAttribute("msg",e.getMessage());
request.getRequestDispatcher("/index.jsp").forward(request, response);
}
}
}
好了,上傳的問題基本就解決了。
下載的實(shí)現(xiàn)
下面我們來看一下下載問題的解決方案
下載文件是我們必須來設(shè)置兩個響應(yīng)頭,設(shè)置Content-Disposition:它的默認(rèn)值為inline,表示在瀏覽器窗口中打開!attachment;filename=xxx要不然我們輸出的內(nèi)容不會彈出保存框,只會顯示在瀏覽器中。
設(shè)置Content-Type:你傳遞給客戶端的文件是什么MIME類型
然后我們就可以new一個輸入流來讀取本地硬盤中的文件,在輸出到ServleoutputStream中
在來一行代碼流過:
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
/**
* 設(shè)置兩個響應(yīng)頭
* 1Content-Type:你傳遞給客戶端的文件是什么MIME類型
* 2Content-Disposition:它的默認(rèn)值為inline,表示在瀏覽器窗口中打開!attachment;filename=xxx
*
* 需要解決的的問題:
* 1 下載文件名中文亂碼問題
* 解決方法:
* 針對不同的瀏覽器使用不同的編碼方式 火狐瀏覽器使用的是Base64編碼,其他瀏覽器一般都是使用url編碼
**/
String mimeType = request.getSession().getServletContext().getMimeType("\\WEB-INF\\tmp\\2\\5\\"
+ "87bd61a4b7c346a5a2e6c072de84acda5.JdbcUtils處理多線程并發(fā)訪問問題.avi");
//解決文件名亂碼問題
String filename = "87bd61a4b7c346a5a2e6c072de84acda5.JdbcUtils處理多線程并發(fā)訪問問題.avi";
filename = encoding(filename, request);
//兩個請求頭
response.setHeader("Content-Type",mimeType);
response.setHeader("Content-Disposition","attachment;filename=" + filename);
ServletOutputStream out = response.getOutputStream();
String path = request.getSession().getServletContext().getRealPath("\\WEB-INF\\tmp\\2\\5\\"
+ "87bd61a4b7c346a5a2e6c072de84acda5.JdbcUtils處理多線程并發(fā)訪問問題.avi");
File file = new File(path);
FileInputStream inputStream = new FileInputStream(file);
IOUtils.copy(inputStream, out, 1024*1024);
}
private String encoding(String filename,HttpServletRequest req) throws UnsupportedEncodingException {
String user_agent = req.getHeader("User-Agent");
String encodingFileName = null;
if(user_agent.contains("Firefox")) {
//按道理來說應(yīng)該使用 BASE64Encoder進(jìn)行編碼,但是不知道為什么不能成功
/*BASE64Encoder base64Encoder = new BASE64Encoder();
encodingFileName = "=?utf-8?B?"
+ base64Encoder.encode(filename.getBytes("utf-8"))
+ "?=";*/
//那我們只能使用這種方式了
encodingFileName = new String(filename.getBytes("UTF-8"), "ISO-8859-1");
}
else {
encodingFileName = URLEncoder.encode(filename,"utf-8");
}
return encodingFileName;
}
}
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
java實(shí)現(xiàn)優(yōu)酷視頻地址解析示例代碼分享
最近做了一個在線視頻的下載器,需要解析youku的視頻,獲得真正的視頻地址,現(xiàn)在把解析過程記錄下來以供參考2014-01-01
兼容Spring Boot 1.x和2.x配置類參數(shù)綁定的工具類SpringBootBindUtil
今天小編就為大家分享一篇關(guān)于兼容Spring Boot 1.x和2.x配置類參數(shù)綁定的工具類SpringBootBindUtil,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2018-12-12
sharding-jdbc 兼容 MybatisPlus動態(tài)數(shù)據(jù)源的配置方法
這篇文章主要介紹了sharding-jdbc 兼容 MybatisPlus動態(tài)數(shù)據(jù)源的配置方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2024-07-07
idea2020安裝MybatisCodeHelper插件的圖文教程
這篇文章主要介紹了idea2020安裝MybatisCodeHelper插件的方法,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-09
maven多profile 打包下 -P參和-D參數(shù)的實(shí)現(xiàn)
這篇文章主要介紹了maven多profile 打包下 -P參和-D參數(shù)的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11
詳解使用Spring?Data?repository進(jìn)行數(shù)據(jù)層的訪問問題
這篇文章主要介紹了使用Spring?Data?repository進(jìn)行數(shù)據(jù)層的訪問,抽象出Spring Data repository是因?yàn)樵陂_發(fā)過程中,常常會為了實(shí)現(xiàn)不同持久化存儲的數(shù)據(jù)訪問層而寫大量的大同小異的代碼,本文給大家介紹的非常詳細(xì),需要的朋友參考下吧2022-06-06
Spring?web開發(fā)教程之Request獲取3種方式
這篇文章主要給大家介紹了關(guān)于Spring?web開發(fā)教程之Request獲取3種方式的相關(guān)資料,request對象是從客戶端向服務(wù)器發(fā)出請求,包括用戶提交的信息以及客戶端的一些信息,需要的朋友可以參考下2023-11-11

