JavaWeb實(shí)現(xiàn)文件上傳與下載的方法
文件上傳概述
實(shí)現(xiàn)web開發(fā)中的文件上傳功能,需完成如下二步操作:
在web頁(yè)面中添加上傳輸入項(xiàng)
在servlet中讀取上傳文件的數(shù)據(jù),并保存到本地硬盤中。
如何在web頁(yè)面中添加上傳輸入項(xiàng)?
<input type=“file”>標(biāo)簽用于在web頁(yè)面中添加文件上傳輸入項(xiàng),設(shè)置文件上傳輸入項(xiàng)時(shí)須注意:
1、必須要設(shè)置input輸入項(xiàng)的name屬性,否則瀏覽器將不會(huì)發(fā)送上傳文件的數(shù)據(jù)。
2、必須把form的enctype屬值設(shè)為multipart/form-data.設(shè)置該值后,瀏覽器在上傳文件時(shí),將把文件數(shù)據(jù)附帶在http請(qǐng)求消息體中,并使用MIME協(xié)議對(duì)上傳的文件進(jìn)行描述,以方便接收方對(duì)上傳數(shù)據(jù)進(jìn)行解析和處理。
文件上傳概述
如何在Servlet中讀取文件上傳數(shù)據(jù),并保存到本地硬盤中?
Request對(duì)象提供了一個(gè)getInputStream方法,通過(guò)這個(gè)方法可以讀取到客戶端提交過(guò)來(lái)的數(shù)據(jù)。但由于用戶可能會(huì)同時(shí)上傳多個(gè)文件,在servlet端編程直接讀取上傳數(shù)據(jù),并分別解析出相應(yīng)的文件數(shù)據(jù)是一項(xiàng)非常麻煩的工作,示例。
為方便用戶處理文件上傳數(shù)據(jù),Apache開源組織提供了一個(gè)用來(lái)處理表單文件上傳的一個(gè)開源組件( Commons-fileupload),該組件性能優(yōu)異,并且其API使用極其簡(jiǎn)單,可以讓開發(fā)人員輕松實(shí)現(xiàn)web文件上傳功能,因此在web開發(fā)中實(shí)現(xiàn)文件上傳功能,通常使用Commons-fileupload組件實(shí)現(xiàn)。
使用Commons-fileupload組件實(shí)現(xiàn)文件上傳,需要導(dǎo)入該組件相應(yīng)的支撐jar包:Commons-fileupload和commons-io。commons-io不屬于文件上傳組件的開發(fā)jar文件,但Commons-fileupload組件從1.1版本開始,它工作時(shí)需要commons-io包的支持。
fileupload組件工作流程
核心API—DiskFileItemFactory
DiskFileItemFactory 是創(chuàng)建 FileItem 對(duì)象的工廠,這個(gè)工廠類常用方法:
public void setSizeThreshold(int sizeThreshold):設(shè)置內(nèi)存緩沖區(qū)的大小,默認(rèn)值為10K。當(dāng)上傳文件大于緩沖區(qū)大小時(shí), fileupload組件將使用臨時(shí)文件緩存上傳文件。
public void setRepository(java.io.File repository):指定臨時(shí)文件目錄,默認(rèn)值為System.getProperty("java.io.tmpdir").
public DiskFileItemFactory(int sizeThreshold, java.io.File repository):構(gòu)造函數(shù)
核心API—ServletFileUpload
ServletFileUpload 負(fù)責(zé)處理上傳的文件數(shù)據(jù),并將表單中每個(gè)輸入項(xiàng)封裝成一個(gè) FileItem 對(duì)象中。常用方法有:
boolean isMultipartContent(HttpServletRequest request):判斷上傳表單是否為multipart/form-data類型
List parseRequest(HttpServletRequest request):解析request對(duì)象,并把表單中的每一個(gè)輸入項(xiàng)包裝成一個(gè)fileItem對(duì)象,并返回一個(gè)保存了所有FileItem的list集合。
setFileSizeMax(long fileSizeMax):設(shè)置上傳文件的最大值
setSizeMax(long sizeMax):設(shè)置上傳文件總量的最大值
setHeaderEncoding(java.lang.String encoding):設(shè)置編碼格式
setProgressListener(ProgressListener pListener)
文件上傳案例
實(shí)現(xiàn)步驟
1、創(chuàng)建DiskFileItemFactory對(duì)象,設(shè)置緩沖區(qū)大小和臨時(shí)文件目錄
2、使用DiskFileItemFactory對(duì)象創(chuàng)建ServletFileUpload對(duì)象,并設(shè)置上傳文件的大小限制。
3、調(diào)用ServletFileUpload.parseRequest方法解析request對(duì)象,得到一個(gè)保存了所有上傳內(nèi)容的List對(duì)象。
4、對(duì)list進(jìn)行迭代,每迭代一個(gè)FileItem對(duì)象,調(diào)用其isFormField方法判斷是否是上傳文件
為普通表單字段,則調(diào)用getFieldName、getString方法得到字段名和字段值
為上傳文件,則調(diào)用getInputStream方法得到數(shù)據(jù)輸入流,從而讀取上傳數(shù)據(jù)。
編碼實(shí)現(xiàn)文件上傳
上傳文件的處理細(xì)節(jié)
中文文件亂碼問題
文件名中文亂碼問題,可調(diào)用ServletUpLoader的setHeaderEncoding方法,或者設(shè)置request的setCharacterEncoding屬性
臨時(shí)文件的刪除問題
由于文件大小超出DiskFileItemFactory.setSizeThreshold方法設(shè)置的內(nèi)存緩沖區(qū)的大小時(shí),Commons-fileupload組件將使用臨時(shí)文件保存上傳數(shù)據(jù),因此在程序結(jié)束時(shí),務(wù)必調(diào)用FileItem.delete方法刪除臨時(shí)文件。
Delete方法的調(diào)用必須位于流關(guān)閉之后,否則會(huì)出現(xiàn)文件占用,而導(dǎo)致刪除失敗的情況。
文件存放位置
為保證服務(wù)器安全,上傳文件應(yīng)保存在應(yīng)用程序的WEB-INF目錄下,或者不受WEB服務(wù)器管理的目錄。
為防止多用戶上傳相同文件名的文件,而導(dǎo)致文件覆蓋的情況發(fā)生,文件上傳程序應(yīng)保證上傳文件具有唯一文件名。
為防止單個(gè)目錄下文件過(guò)多,影響文件讀寫速度,處理上傳文件的程序應(yīng)根據(jù)可能的文件上傳總量,選擇合適的目錄結(jié)構(gòu)生成算法,將上傳文件分散存儲(chǔ)。
文件下載
因?yàn)橐螺d的文件可以是各種類型的文件,所以要將文件傳送給客戶端,其相應(yīng)內(nèi)容應(yīng)該被當(dāng)做二進(jìn)制來(lái)處理,所以應(yīng)該調(diào)用 方法返回 ServeltOutputStream對(duì)象來(lái)向客戶端寫入文件內(nèi)容。
下載案例
遍歷上傳目錄下的所有文件顯示給用戶,并允許用戶完成下載。
(讀取某一個(gè)文件夾下的所有的文件,存到集合里面List,再存到request作用域范圍中)ListFileServelt—(將所有的文件列表顯示)Listfiles.jsp-----DownloaServlet.java private String id; private String savename; //上傳文件的名稱,文件的uuid名 private String realName; //上傳文件的真實(shí)名稱 private String savepath; //記住文件的位置 private Date uptime; //文件的上傳時(shí)間 private String description; //文件的描述 private String username; //上傳人 ListFileServlet package com.hbsi.servlet; import java.io.File; import java.io.IOException; import java.io.PrintWriter; import java.util.HashMap; import java.util.Map; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; importjavax.servlet.http.HttpServletRequest; importjavax.servlet.http.HttpServletResponse; public class ListFileServlet extendsHttpServlet { publicvoid doGet(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException { Stringsavepath = this.getServletContext().getRealPath( "/WEB-INF/upload"); Mapmap = new HashMap(); listFiles(newFile(savepath), map); request.setAttribute("map",map); request.getRequestDispatcher("/listfile.jsp") .forward(request,response); } privatevoid listFiles(File file, Map map) { if(file.isFile()) { Stringuuidname = file.getName(); // uuid_a_1_3_3.txt Stringrealname = uuidname.substring(uuidname.indexOf("_") + 1); map.put(uuidname,realname); }else { File[]files = file.listFiles(); for(File f : files) { listFiles(f,map); } } } publicvoid doPost(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException { doGet(request,response); } } DownloadServlet package com.hbsi.servlet; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; import java.net.URLEncoder; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; importjavax.servlet.http.HttpServletRequest; importjavax.servlet.http.HttpServletResponse; public class DownloadServlet extendsHttpServlet { publicvoid doGet(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException { Stringfilename = request.getParameter("filename"); filename= new String(filename.getBytes("iso8859-1"), "utf-8"); System.out.println(filename); Stringsavepath = this.getFileSavePath(this.getRealName(filename)); Filef = new File(savepath + "\\" + filename); if(!f.exists()) { request.setAttribute("message","下載的資源不存在"); request.getRequestDispatcher("/message.jsp").forward(request,response); } response.setHeader("content-disposition","attachment;filename="+ URLEncoder.encode(this.getRealName(filename),"UTF-8")); FileInputStreamin = new FileInputStream(f); byte[]buf = new byte[1024]; intlen = 0; OutputStreamout = response.getOutputStream(); while((len = in.read(buf)) > 0) { out.write(buf,0, len); } in.close(); } publicString getFileSavePath(String filename) { intdir1 = filename.hashCode() & 0xf; intdir2 = (filename.hashCode() >> 4) & 0xf; Stringsavepath = this.getServletContext().getRealPath("/WEB-INF/upload")+"\\" + dir1 + "\\" + dir2; returnsavepath; } publicString getRealName(String filename) { StringrealName = filename.substring(filename.indexOf("_") + 1); returnrealName; } publicvoid doPost(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException { doGet(request,response); } }
- JavaWeb實(shí)現(xiàn)文件上傳下載功能實(shí)例解析
- JavaWeb實(shí)現(xiàn)文件上傳下載功能實(shí)例詳解
- Javaweb實(shí)現(xiàn)上傳下載文件的多種方法
- JavaWeb文件上傳下載實(shí)例講解(酷炫的文件上傳技術(shù))
- JavaWeb項(xiàng)目實(shí)現(xiàn)文件上傳動(dòng)態(tài)顯示進(jìn)度實(shí)例
- JavaWeb實(shí)現(xiàn)多文件上傳及zip打包下載
- JavaWeb中struts2實(shí)現(xiàn)文件上傳下載功能實(shí)例解析
- javaweb實(shí)現(xiàn)文件上傳示例代碼
- JavaWeb實(shí)現(xiàn)文件上傳與下載實(shí)例詳解
- JavaWeb實(shí)現(xiàn)簡(jiǎn)單上傳文件功能
相關(guān)文章
SpringBoot FreeWorker模板技術(shù)解析
這篇文章主要介紹了SpringBoot FreeWorker模板技術(shù)解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-11-11Java中BigInteger與BigDecimal類用法總結(jié)
在Java中有兩個(gè)用于大數(shù)字運(yùn)算的類,分別是java.math.BigInteger類 和 java.math.BigDecimal類,這兩個(gè)類都可以用于高精度計(jì)算,BigInteger類是針對(duì)整型大數(shù)字的處理類,而BigDecimal類是針對(duì)大小數(shù)的處理類,接下來(lái)帶大家來(lái)學(xué)習(xí)一下,在Java中如何處理大數(shù)字2023-05-05SpringMVC?RESTFul實(shí)現(xiàn)列表功能
這篇文章主要為大家介紹了SpringMVC?RESTFul實(shí)現(xiàn)列表功能詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05Java中RabbitMQ延遲隊(duì)列實(shí)現(xiàn)詳解
這篇文章主要介紹了Java中RabbitMQ延遲隊(duì)列實(shí)現(xiàn)詳解,消息過(guò)期后,根據(jù)routing-key的不同,又會(huì)被死信交換機(jī)路由到不同的死信隊(duì)列中,消費(fèi)者只需要監(jiān)聽對(duì)應(yīng)的死信隊(duì)列進(jìn)行消費(fèi)即可,需要的朋友可以參考下2023-09-09