摘要:翻了幾篇教程,寫(xiě)出來(lái)了一個(gè)簡(jiǎn)單的文件上傳接收代碼。這里我們就真正建了一個(gè)的實(shí)例來(lái)處理文件的上傳??梢栽O(shè)置上傳文件的最大大小。參考的文章實(shí)現(xiàn)基本文件上傳在中使用開(kāi)源包實(shí)現(xiàn)文件上傳功能
文件上傳可以說(shuō)是Web應(yīng)用中很常用的一塊,前幾天打算研究一下HTML5提供的FileReader API,并且用Tomcat作為后端來(lái)實(shí)驗(yàn)大文件的上傳(只是學(xué)校的課程作業(yè)必須用Java寫(xiě),都不允許使用最好的編程語(yǔ)言php>.<)??蒍ava Servlet與php這種喜聞樂(lè)見(jiàn)的Web碼農(nóng)語(yǔ)言不同,并沒(méi)有提供一個(gè)很簡(jiǎn)單的處理文件上傳的API,所以還搗鼓了蠻久,也對(duì)一般的文件上傳的HTML控件和實(shí)現(xiàn)原理稍微有了一點(diǎn)了解。
對(duì)面宿舍的一位同學(xué)說(shuō)我很久沒(méi)更了不太好,于是我就寫(xiě)一篇,謝謝他的提醒。
首先,我們都知道最常見(jiàn)的HTML的文件上傳控件是喜聞樂(lè)見(jiàn)的,但一定要搭配form的屬性enctype="multipart/form-data",服務(wù)器上要有一個(gè)接收上傳的cgi或者別的什么,既然我們用java寫(xiě),就叫uploadServlet。于是有了一個(gè)如下的常見(jiàn)的上傳表單。
然后我們?cè)诤蠖颂幚?。由于Java Servlet的API是沒(méi)有提供什么$_FILES數(shù)組這樣傻瓜式的文件操控方式,我們必須自己處理request。我們不妨先把收到的request輸出到文件當(dāng)中,看看Servlet會(huì)收到什么,再想想怎么處理。放這樣一個(gè)servlet的代碼:
import javax.servlet.*; import javax.servlet.http.*; import java.io.*; public class UploadServlet extends HttpServlet{ @Override public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{ response.setContentType("text/plain;charset=utf-8"); PrintWriter writer=response.getWriter(); InputStream in=request.getInputStream(); File f = new File("/tmp/upload"); //把文件存到/tmp/upload FileOutputStream fout = new FileOutputStream(f); byte[] b=new byte[1024]; int n=0; while ((n=in.read(b))!=-1){ fout.write(b,0,n); } fout.close(); in.close(); writer.println("Finished uploading files!"); writer.close(); } }
有了Servlet就拖出去跑一跑。這里我的表單不僅會(huì)發(fā)送文件,還會(huì)發(fā)送一個(gè)密碼域。如果我隨便發(fā)一個(gè)文本文件,那么我得到了這樣的結(jié)果。
多上傳幾次還會(huì)發(fā)現(xiàn)那一堆橫杠開(kāi)頭的數(shù)字會(huì)變動(dòng)。這下不好玩了,雖然我們可以看到我們上傳的數(shù)據(jù),但要解析它有點(diǎn)過(guò)于復(fù)雜了。這個(gè)請(qǐng)求是依據(jù)RFC1867來(lái)寫(xiě)的,雖然有標(biāo)準(zhǔn)可依,但我們這么懶怎么會(huì)去依照標(biāo)準(zhǔn)寫(xiě)一個(gè)解析器呢?
于是我們需要請(qǐng)出Apache開(kāi)發(fā)的文件上傳處理庫(kù)Commons FileUpload。這個(gè)網(wǎng)站提供了最新版的下載鏈接和基本的使用指南。文檔講得過(guò)于全面了,而我們一般不需要那么多功能,夠用就好。翻了幾篇教程,寫(xiě)出來(lái)了一個(gè)簡(jiǎn)單的文件上傳接收代碼。
javaimport javax.servlet.*; import javax.servlet.http.*; import java.io.*; import java.util.*; import org.apache.commons.fileupload.*; import org.apache.commons.fileupload.servlet.*; import org.apache.commons.fileupload.disk.*;
首先需要多裝載三個(gè)庫(kù),以及一個(gè)java.util.List,因?yàn)榈綍r(shí)候處理的時(shí)候,Commons FileUpload會(huì)把搞成一個(gè)List返回回來(lái),我們需要接收這個(gè)List并處理解析它。
public class UploadServlet extends HttpServlet{ private String filepath; private String temppath; private String buf; public void init(ServletConfig config) throws ServletException{ super.init(config); ServletContext context=getServletContext(); filepath=context.getRealPath("/"+config.getInitParameter("filepath")); temppath=context.getRealPath("/"+config.getInitParameter("temppath")); }
為了方便維護(hù),我把保存上傳文件的目錄用Init Parameter的方式寫(xiě)到web.xml里面去,然后在這個(gè)地方讀出來(lái)。我們需要一個(gè)保存上傳文件的目錄和一個(gè)用來(lái)做緩存的臨時(shí)目錄。如果你接收上傳文件之后不打算保存而是直接拿去處理,也沒(méi)有問(wèn)題,但是一定要有一個(gè)緩存目錄,在后面有用。
接下來(lái)是真正激動(dòng)人心的處理上傳的代碼了。我懶得寫(xiě)doGet了所以就只有一個(gè)doPost。
@Override public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{ response.setContentType("text/plain;charset=utf-8"); PrintWriter writer=response.getWriter(); int count=0; try{ DiskFileItemFactory diskFactory = new DiskFileItemFactory(); diskFactory.setSizeThreshold(4 *1024 ); diskFactory.setRepository(new File(temppath));
這里我們開(kāi)了一個(gè)diskFactory,就是FileUpload所需要使用的緩存,當(dāng)內(nèi)存存不下上傳的文件的時(shí)候,它會(huì)自動(dòng)寫(xiě)入緩存目錄。通過(guò)setSizeThreshold方法可以設(shè)置內(nèi)存的使用上限,也就是當(dāng)內(nèi)存用了這么多卻還存不下,就開(kāi)始寫(xiě)緩存。顯然這個(gè)值很大程度上會(huì)決定這個(gè)Servlet的效率。
ServletFileUpload upload = new ServletFileUpload(diskFactory); upload.setSizeMax(4 * 1024 * 1024); List fileItems = upload.parseRequest(request); Iterator iter = fileItems.iterator();
這里我們就真正建了一個(gè)ServletFileUpload的實(shí)例upload來(lái)處理文件的上傳??梢栽O(shè)置上傳文件的最大大小。然后把request對(duì)象直接交給upload來(lái)解析,它會(huì)返回一個(gè)一個(gè)List,這個(gè)List的每一項(xiàng)實(shí)際上是一個(gè)FileItem對(duì)象,后面就要用迭代器處理這個(gè)列表。
while (iter.hasNext()){ FileItem item = (FileItem) iter.next(); if (item.isFormField()){ writer.println(item.getFieldName()+" : "+item.getString()); }
要注意的是ServletFileUpload也會(huì)處理非文件的信息,可以用isFormField方法來(lái)檢查,然后將信息獲取出來(lái)。但這在這里不是重點(diǎn),只是必須要處理掉而已。
else{ String filename = item.getName(); filename = filename.substring( filename.lastIndexOf("")+1,filename.length()); File uploadFile = new File(filepath+"/"+filename); item.write(uploadFile); writer.println("Get file:"+ filename); writer.println(" filetype: "+item.getContentType()); count++; } } } catch (Exception e){ e.printStackTrace(); } writer.println("Finished uploading files!"); writer.close(); } }
處理文件的代碼就這么點(diǎn),如果還要說(shuō)什么的話,就是每個(gè)文件的FileItem對(duì)象不僅可以用write方法來(lái)直接寫(xiě)到什么文件里面去,也可以用getInputStream方法得到一個(gè)輸入流來(lái)解析,或者用get方法直接讀到一個(gè)byte數(shù)組里面去。可以說(shuō)這個(gè)庫(kù)提供了一個(gè)很方便的方法解析上傳的文件。
最后提一下,Apache Commons是一個(gè)Java增強(qiáng)庫(kù),提供了大量的優(yōu)質(zhì)Java資源庫(kù),涉及很多開(kāi)發(fā)領(lǐng)域。如果不出意外,應(yīng)該我會(huì)在近期寫(xiě)一篇關(guān)于JavaScript FileReader的blog,敬請(qǐng)期待。
參考的文章:
Servlet實(shí)現(xiàn)基本文件上傳
在Servlet中使用開(kāi)源fileupload包實(shí)現(xiàn)文件上傳功能
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/35743.html
摘要:第一步搭環(huán)境基本我們要清楚自己的版本。因?yàn)槲覀兣渲玫某晒Φ那疤崾前姹鞠鄬?duì)應(yīng)。解壓縮都隨便一個(gè)盤(pán)都行,下圖是我的路徑配置相關(guān)環(huán)境變量,由于本人之前已經(jīng)配置了開(kāi)發(fā)時(shí)環(huán)境,即。這個(gè)顯示上傳狀態(tài)與后面在中有定義。 第一步: 搭環(huán)境,基本jdk 1.6+apache tomcat6.0+myeclipse2014 1.我們要清楚自己的jdk版本。因?yàn)槲覀傾pache Tomcat配置的成...
摘要:第一步搭環(huán)境基本我們要清楚自己的版本。因?yàn)槲覀兣渲玫某晒Φ那疤崾前姹鞠鄬?duì)應(yīng)。解壓縮都隨便一個(gè)盤(pán)都行,下圖是我的路徑配置相關(guān)環(huán)境變量,由于本人之前已經(jīng)配置了開(kāi)發(fā)時(shí)環(huán)境,即。這個(gè)顯示上傳狀態(tài)與后面在中有定義。 第一步: 搭環(huán)境,基本jdk 1.6+apache tomcat6.0+myeclipse2014 1.我們要清楚自己的jdk版本。因?yàn)槲覀傾pache Tomcat配置的成...
摘要:要使用容器上傳文件,您需要注冊(cè)一個(gè)類(lèi)在中。最好不要使用內(nèi)容加載應(yīng)用程序的文件系統(tǒng)。允許用戶上傳文件的表單從后端提供的文件列表調(diào)整文件上傳限制配置文件上傳時(shí),設(shè)置文件大小限制通常很有用。 本指南將指導(dǎo)您完成創(chuàng)建可以接收HTTP多文件上傳服務(wù)器應(yīng)用程序的過(guò)程。 你要構(gòu)建什么 您將創(chuàng)建一個(gè)接受文件上傳的Spring Boot Web應(yīng)用程序。您還將構(gòu)建一個(gè)簡(jiǎn)單的HTML界面來(lái)上傳測(cè)試文件。 ...
摘要:前言案例使用的開(kāi)發(fā)工具不足之處希望各位大佬們多多指教頂包文件代碼圖片路徑選擇圖片代碼圖片上傳選完文件后,是否自動(dòng)上傳。內(nèi)部根據(jù)當(dāng)前運(yùn)行是創(chuàng)建,可能是元素,也可能是這里是的文件上傳方式,或者。默認(rèn)值設(shè)置文件上傳域的。 前言: ????????案例使用的開(kāi)發(fā)工具:eclipse ? ? ? ? ...
摘要:一添加項(xiàng)目依賴二上傳上傳文件存儲(chǔ)目錄上傳配置上傳文件最大值檢測(cè)是否為多媒體上傳如果不是則停止表單必須包含配置上傳參數(shù)設(shè)置最大文件上傳值中文處理構(gòu)造臨時(shí)路徑來(lái)存儲(chǔ)上傳的文件這個(gè)路徑相對(duì)當(dāng)前應(yīng)用的目錄如果目錄不存在則創(chuàng)建解析請(qǐng)求的內(nèi)容 一、添加項(xiàng)目依賴(gradle) dependencies { compile group: javax.servlet, name: javax....
閱讀 966·2021-11-23 09:51
閱讀 939·2021-11-23 09:51
閱讀 2654·2021-11-15 18:01
閱讀 4008·2021-10-11 11:07
閱讀 2526·2021-09-22 15:30
閱讀 1220·2021-09-22 14:59
閱讀 1666·2019-08-30 15:55
閱讀 1843·2019-08-30 15:52