JavaWeb servlet實(shí)現(xiàn)下載與上傳功能的方法詳解
本文實(shí)例講述了JavaWeb servlet實(shí)現(xiàn)下載與上傳功能的方法。分享給大家供大家參考,具體如下:
本文內(nèi)容:
- servlet實(shí)現(xiàn)下載功能
- servlet實(shí)現(xiàn)上傳功能
首發(fā)日期:2018-07-21
servlet實(shí)現(xiàn)下載功能
實(shí)現(xiàn)流程
1.首先制作一個(gè)jsp頁(yè)面,主要是用來(lái)觸發(fā)下載的。這里可以根據(jù)你的想法來(lái)做,當(dāng)然servlet那邊就要相應(yīng)的更改了。我這里使用一個(gè)簡(jiǎn)單的a標(biāo)簽來(lái)觸發(fā)。
![]()
2.設(shè)置響應(yīng)信息,告訴瀏覽器要將傳過(guò)來(lái)的數(shù)據(jù)識(shí)別成下載;根據(jù)提交上來(lái)的數(shù)據(jù)找到對(duì)應(yīng)文件,轉(zhuǎn)成流,返回給瀏覽器;

中文文件名問(wèn)題:
- 雖然真的不建議使用中文文件名。但還是給一下處理手段。
先給出觸發(fā)的條件:![]()
中文文件名需要解決兩個(gè)問(wèn)題:
1.瀏覽器提交上來(lái)的中文文件名要識(shí)別:這里是普通的get和post的中文數(shù)據(jù)問(wèn)題
get方式:String filename = new String(filename.getBytes("iso-8859-1"),"utf-8"); 【tomcat8不需要】
post方式:request.setCharacterEncoding("utf-8")
2.返回給瀏覽器時(shí),瀏覽器能識(shí)別,即能正確顯示回來(lái)的下載文件名(如果你下載東西遇到過(guò)文件名亂碼,就是這個(gè)沒(méi)處理好):
處理方法:

protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 1.獲取下載目標(biāo)
String filename = request.getParameter("target");
System.out.println(filename);
// 2.找到下載目標(biāo)
String path = getServletContext().getRealPath("download/" + filename);
File file = new File(path);
if (file.exists()) {
// 3.如果文件存在,那么設(shè)置響應(yīng)的內(nèi)容為下載,告訴瀏覽器將信息識(shí)別成下載
// 判斷一下瀏覽器
String agent = request.getHeader("User-Agent");
if (agent.contains("Firefox")) {// 火狐
BASE64Encoder base64Encoder = new BASE64Encoder();
filename = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
} else {// ie和谷歌
filename = URLEncoder.encode(filename, "utf-8");
}
response.setHeader("Content-Disposition", "attachment; filename=" + filename);
// 4.獲取文件流
FileInputStream fis = new FileInputStream(file);
OutputStream os = response.getOutputStream();
// 5.返回給瀏覽器
int len = 0;
byte[] buffer = new byte[1024];
while ((len = fis.read(buffer)) != -1) {
os.write(buffer, 0, len);
}
os.flush();// flush一下,確保一下
os.close();
fis.close();
} else {
response.setContentType("text/html;charset=UTF-8");
response.getWriter().write("找不到文件");
}
}
servlet實(shí)現(xiàn)上傳功能
1.創(chuàng)建一個(gè)頁(yè)面,用于上傳:【這里只用了一個(gè)上傳,但事實(shí)上下面的代碼是支持多個(gè)上傳的】

【當(dāng)使用了enctype="multipart/form-data"之后,普通輸入框的內(nèi)容,將無(wú)法使用getParameter獲取】
2.導(dǎo)入包,以便使用fileupload:commons-fileupload-1.2.1.jar和commons-io-1.4.jar【這里導(dǎo)入io包主要是用于io流對(duì)接,上傳的文件流直接對(duì)接輸出流;如果你不導(dǎo)入,那么需要手動(dòng)處理流中的數(shù)據(jù)!】
3.創(chuàng)建DiskFileItemFactory工廠類,用來(lái):DiskFileItemFactory factory=new DiskFileItemFactory();
4.創(chuàng)建解析類,用于解析resquest:ServletFileUpload upload=new ServletFileUpload(factory);
5.解析內(nèi)容,獲取一個(gè)list,數(shù)據(jù)都存儲(chǔ)在list中:List<FileItem> list = upload.parseRequest(request);
現(xiàn)在信息封裝方法已經(jīng)跟之前沒(méi)有文件上傳時(shí)不一樣了,所以需要解析:

6.操作list【list中的每一個(gè)元素都是FileItem對(duì)象,可以用FileItem對(duì)象.isFormField()來(lái)判斷是否是表單項(xiàng)(認(rèn)為文件是上傳項(xiàng));如果是真的話,說(shuō)明是普通的輸入框內(nèi)容,如果你想要存儲(chǔ)輸入框提交的內(nèi)容,那么這里可以處理一下;不為真說(shuō)明是上傳項(xiàng),這里可以針對(duì)流進(jìn)行操作】
如何操作?
對(duì)于普通表單項(xiàng):item.getFieldName()可以獲取對(duì)應(yīng)的name;item.getString()可以獲取對(duì)應(yīng)的值
對(duì)于上傳項(xiàng),需要操作它的流:item.getInputStream()可以獲取對(duì)應(yīng)的數(shù)據(jù)流。
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
DiskFileItemFactory factory=new DiskFileItemFactory();//1.創(chuàng)建DiskFileItemFactory工廠類
ServletFileUpload upload=new ServletFileUpload(factory);//2.創(chuàng)建解析類,用于解析resquest
try {
List<FileItem> list = upload.parseRequest(request);//3.解析內(nèi)容,獲取一個(gè)list,數(shù)據(jù)都存儲(chǔ)在list中
for(FileItem item:list) {
if(item.isFormField()) {//判斷是否是普通的表單內(nèi)容
System.out.println(item.getFieldName());//獲取的是表單中name屬性的值
System.out.println(item.getString());//獲取的是對(duì)應(yīng)的表單的值
}else {//為假,說(shuō)明是上傳項(xiàng)
//獲取流,進(jìn)行處理
InputStream ism = item.getInputStream();
String path=getServletContext().getRealPath("/upload/");
System.out.println(path);
String filename = item.getName();//這里getName可以獲取文件名
System.out.println(filename);
File file=new File(path+filename);
file.createNewFile();//這里不做文件存在性和名字重復(fù)判斷
OutputStream fos = new FileOutputStream(file);
//這里直接借助commons.io來(lái)做io對(duì)接,不然需要做流的讀取和寫(xiě)入
IOUtils.copy(ism,fos);//把輸入流的數(shù)據(jù)拷貝到輸出流
IOUtils.closeQuietly(ism);
IOUtils.closeQuietly(fos);
}
}
} catch (FileUploadException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
更多關(guān)于java算法相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Java文件與目錄操作技巧匯總》、《Java數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Java操作DOM節(jié)點(diǎn)技巧總結(jié)》和《Java緩存操作技巧匯總》
希望本文所述對(duì)大家java程序設(shè)計(jì)有所幫助。
相關(guān)文章
nacos單機(jī)版啟動(dòng)失敗問(wèn)題以及解決
這篇文章主要介紹了nacos單機(jī)版啟動(dòng)失敗問(wèn)題以及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07
java使用FFmpeg合成視頻和音頻并獲取視頻中的音頻等操作(實(shí)例代碼詳解)
這篇文章主要介紹了java使用FFmpeg合成視頻和音頻并獲取視頻中的音頻等操作,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-02-02
Netty分布式高性能工具類recycler的使用及創(chuàng)建
這篇文章主要為大家介紹了Netty分布式高性能工具類recycler的使用和創(chuàng)建,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2022-03-03
基于SpringBoot集成測(cè)試遠(yuǎn)程連接Redis服務(wù)的教程詳解
這篇文章主要介紹了基于SpringBoot集成測(cè)試遠(yuǎn)程連接的Redis服務(wù)的相關(guān)知識(shí),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-03-03
Java實(shí)現(xiàn)駝峰和下劃線互相轉(zhuǎn)換的示例代碼
Java對(duì)各種變量、方法和類等要素命名時(shí)使用的字符序列稱為標(biāo)識(shí)符,凡是自己可以起名字的地方都叫標(biāo)識(shí)符。本文為大家分享了Java中如何實(shí)現(xiàn)駝峰命名與下劃線命名的互轉(zhuǎn),感興趣的可以了解一下2022-05-05

