問題:JavaWeb中實(shí)現(xiàn)文件上傳的方式有哪些秉撇?

問題:JavaWeb中實(shí)現(xiàn)文件上傳的方式有哪些?

上回我們說了下文件下載的方式有哪些遵湖,這次我們從不同的環(huán)境下簡單來說說文件上傳的方式有哪些粱快。

文件上傳的方式

Servlet2.5 方式

Servlet3.0 方式

SpringMVC 方式

案例實(shí)操

Servlet2.5 方式

文件上傳涉及到前臺(tái)頁面的編寫和后臺(tái)服務(wù)器端代碼的編寫伸眶,前臺(tái)發(fā)送文件杨凑,后臺(tái)接收并保存文件,這才是一個(gè)完整的文件上傳晴楔。

1) 前臺(tái)頁面

在做文件上傳的時(shí)候顿苇,會(huì)有一個(gè)上傳文件的界面,首先我們需要一個(gè)表單税弃,并且表單的請(qǐng)求方式為 POST纪岁;其次我們的 form 表單的 enctype 必須設(shè)為”multipart/form-data”即 enctype="multipart/form-data" 意思是設(shè)置表單的 MIME 編碼。默認(rèn)情況下這個(gè)編碼格式是 ”application/x-www-form-urlencoded”则果,不能用于文件上傳幔翰;只有使用了 multipart/form-data 才能完整地傳遞文件數(shù)據(jù)漩氨。

<!DOCTYPE html>

<html>

<head>

<metacharset="UTF-8">

<title>上傳文件</title>

</head>

<body>

? ? <formaction="uploadServlet"method="post"enctype="multipart/form-data">

? ? ? ? 文件:<inputtype="file"name="myfile"/>

? ? ? ? <inputtype="submit"value="上傳"/>

? ? </form>

</body>

</html>

2) 后臺(tái) commons-fileupload 的使用

首先需要導(dǎo)入第三方j(luò)ar包,http://commons.apache.org/? 下載 commons-io 和 commons-fileupload 兩個(gè)jar的資源遗增。解壓并導(dǎo)入到項(xiàng)目中才菠。commons-fileupload.jar 是文件上傳的核心包 commons-io.jar 是 fileupload 的依賴包,同時(shí)又是一個(gè)工具包贡定。

介紹一下使用到的幾個(gè)核心類

??DiskFileItemFactory – 設(shè)置磁盤空間,保存臨時(shí)文件可都。只是一個(gè)工具類

??ServletFileUpload – 文件上傳的核心類缓待,此類接收 request,并解析

??ServletFileUpload.parseRequest(request); – List 解析 request

??1渠牲、創(chuàng)建一個(gè) DiskFileItemFactory 工廠類旋炒,并制定臨時(shí)文件和大小

??2、創(chuàng)建 ServletFileUpload 核心類签杈,接收臨時(shí)文件瘫镇,做請(qǐng)求的轉(zhuǎn)換

??3、通過 ServletFileUpload 類轉(zhuǎn)換原始請(qǐng)求答姥,得到 FileItem 集合

??4铣除、遍歷集合中的各個(gè)元素并處理

??5、判斷每個(gè)元素是否是普通表單項(xiàng)鹦付,如果是則按照普通表單項(xiàng)處理

??6尚粘、如果不是普通表單項(xiàng),則是文件敲长,通過處理的方式進(jìn)行處理(上傳)

publicclassUploadServletextendsHttpServlet{

? ? privatestaticfinallongserialVersionUID=1L;

?

? ? protectedvoidservice(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{

? ? ? ? // 設(shè)定編碼郎嫁,可以獲取中文文件名

? ? ? ? request.setCharacterEncoding("UTF-8");

? ? ? ? // 獲取tomcat下的upload目錄的路徑

? ? ? ? Stringpath=getServletContext().getRealPath("/upload");

? ? ? ? // 臨時(shí)文件目錄

? ? ? ? StringtempPath=getServletContext().getRealPath("/temp");

? ? ? ? // 檢查我們是否有文件上傳請(qǐng)求

? ? ? ? // boolean isMultipart = ServletFileUpload.isMultipartContent(req);

? ? ? ? // 1、聲明DiskFileItemFactory工廠類祈噪,用于在指定磁盤上設(shè)置一個(gè)臨時(shí)目錄

? ? ? ? DiskFileItemFactorydisk=newDiskFileItemFactory(1024*10,newFile(tempPath));

? ? ? ? // 2泽铛、聲明ServletFileUpload,接收上面的臨時(shí)文件辑鲤。也可以默認(rèn)值

? ? ? ? ServletFileUploadup=newServletFileUpload(disk);

? ? ? ? // 3盔腔、解析request

? ? ? ? try{

? ? ? ? ? ? List<FileItem>list=up.parseRequest(request);

? ? ? ? ? ? if(list.size()>0) {

? ? ? ? ? ? ? ? for(FileItemfile:list) {

? ? ? ? ? ? ? ? ? ? // 判斷是否是普通的表單項(xiàng)

? ? ? ? ? ? ? ? ? ? if(file.isFormField()) {

? ? ? ? ? ? ? ? ? ? ? ? StringfieldName=file.getFieldName();

? ? ? ? ? ? ? ? ? ? ? ? // 中文亂碼,此時(shí)還需要指定獲取數(shù)據(jù)的編碼方式

? ? ? ? ? ? ? ? ? ? ? ? // String value = file.getString();

? ? ? ? ? ? ? ? ? ? ? ? Stringvalue=file.getString("UTF-8");

? ? ? ? ? ? ? ? ? ? ? ? System.out.println(fieldName+"="+value);

? ? ? ? ? ? ? ? ? ? }else{// 說明是一個(gè)文件

? ? ? ? ? ? ? ? ? ? ? ? // 獲取文件本身的名稱

? ? ? ? ? ? ? ? ? ? ? ? StringfileName=file.getName();

? ? ? ? ? ? ? ? ? ? ? ? System.out.println(file.getFieldName());

? ? ? ? ? ? ? ? ? ? ? ? // 處理文件名稱

? ? ? ? ? ? ? ? ? ? ? ? fileName=fileName.substring(fileName.lastIndexOf("\\")+1);

? ? ? ? ? ? ? ? ? ? ? ? System.out.println("old Name : "+fileName);

? ? ? ? ? ? ? ? ? ? ? ? // 修改名稱

? ? ? ? ? ? ? ? ? ? ? ? StringextName=fileName.substring(fileName.lastIndexOf("."));

? ? ? ? ? ? ? ? ? ? ? ? StringnewName=UUID.randomUUID().toString().replace("-","")+extName;

? ? ? ? ? ? ? ? ? ? ? ? // 保存新的名稱遂填,并寫出到新文件中

? ? ? ? ? ? ? ? ? ? ? ? file.write(newFile(path+"/"+newName));

? ? ? ? ? ? ? ? ? ? ? ? System.out.println("文件名是:"+fileName);

? ? ? ? ? ? ? ? ? ? ? ? System.out.println("文件大小是:"+file.getSize());

? ? ? ? ? ? ? ? ? ? ? ? file.delete();

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? }catch(FileUploadExceptione) {

? ? ? ? ? ? e.printStackTrace();

? ? ? ? }catch(Exceptione) {

? ? ? ? ? ? e.printStackTrace();

? ? ? ? }

? ? }

?

}

Servlet3.0 方式

使用注解 @MultipartConfig 將一個(gè) Servlet 標(biāo)識(shí)為支持文件上傳铲觉。Servlet3.0 將 multipart/form-data 的 POST 請(qǐng)求封裝成 Part,通過 Part 對(duì)上傳的文件進(jìn)行操作吓坚。

前臺(tái)

<!DOCTYPE html>

<html>

<head>

<metacharset="UTF-8">

<title>上傳文件</title>

</head>

<body>

? ? <formaction="upload"method="post"enctype="multipart/form-data">

? ? ? ? 姓名:<inputtype="text"name="uname"/>

? ? ? ? 文件:<inputtype="file"name="myfile"/>

? ? ? ? <inputtype="submit"value="上傳"/>

? ? </form>

</body>

</html>

后臺(tái)

@WebServlet("/upload")

@MultipartConfig

publicclassUploadServletextendsHttpServlet{

? ? privatestaticfinallongserialVersionUID=1L;

?

? ? protectedvoidservice(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{

? ? ? ? System.out.println("上傳文件...");

? ? ? ? // 設(shè)置編碼

? ? ? ? request.setCharacterEncoding("UTF-8");

? ? ? ? // 獲取普通表單項(xiàng)參數(shù)

? ? ? ? Stringuname=request.getParameter("uname");

? ? ? ? System.out.println(uname);

? ? ? ? // 上傳文件

? ? ? ? // 得到part對(duì)象 request.getpart(name):name代表的是表單中file元素的name屬性值

? ? ? ? Partpart=request.getPart("myfile");

? ? ? ? // 得到文件存放的路徑

? ? ? ? Stringpath=request.getServletContext().getRealPath("/");

? ? ? ? // 得到文件名

? ? ? ? StringfileName=part.getSubmittedFileName();

? ? ? ? // 上傳

? ? ? ? part.write(path+fileName);

? ? }

?

}

SpringMVC 方式

Pom 文件修改 添加 commons-fileupload 依賴

<dependency>

?

<groupId>commons-fileupload</groupId>

?

<artifactId>commons-fileupload</artifactId>

?

<version>1.3.2</version>

?

</dependency>

servlet-context.xml

<beanid="multipartResolver"class="org.springframework.web.multipart.commons.CommonsMultipartResolver">

?

<propertyname="maxUploadSize">

?

<value>104857600</value>

?

</property>

?

<propertyname="maxInMemorySize">

?

<value>4096</value>

?

</property>

?

</bean>

FileController

importjava.io.File;

?

importjava.io.IOException;

?

importjavax.servlet.http.HttpServletRequest;

?

importorg.springframework.stereotype.Controller;

?

importorg.springframework.web.bind.annotation.RequestMapping;

?

importorg.springframework.web.multipart.MultipartFile;

?

importorg.springframework.web.multipart.MultipartHttpServletRequest;

?

importorg.springframework.web.servlet.ModelAndView;

?

@Controller

?

publicclassFileController{

?

@RequestMapping("/uploadFile")

?

publicModelAndViewuploadFile(HttpServletRequestrequest){

?

ModelAndViewmv=newModelAndView();

?

mv.setViewName("result");

?

MultipartHttpServletRequestmr=(MultipartHttpServletRequest)request;

?

MultipartFilemultipartFile=mr.getFile("file");

?

Stringpath=request.getSession().getServletContext().getRealPath("upload");

?

System.out.println(path);

?

if(null!=multipartFile&&!multipartFile.isEmpty()){

?

? ? StringfileName=multipartFile.getOriginalFilename();

?

try{

?

? ? multipartFile.transferTo(newFile(path,fileName));

?

? ? mv.addObject("msg","文件上傳成功!");

?

}catch(Exceptione) {

?

? ? mv.addObject("msg","上傳失敗!");

?

? ? e.printStackTrace();

?

? ? ?? }

?

? ? ?? }

?

returnmv;

?

? ? }

?

}

前臺(tái)表單

<formaction="uploadFile"method="post"enctype="multipart/form-data">

?

? ? <inputtype="file"name="file"/>

?

? ? <buttontype="submit">提交</button>

?

</form>

擴(kuò)展~MIME

MIME(Multipurpose Internet Mail Extensions)多用途互聯(lián)網(wǎng)郵件擴(kuò)展類型撵幽。是設(shè)定某種擴(kuò)展名的文件用一種應(yīng)用程序來打開的方式類型,當(dāng)該擴(kuò)展名文件被訪問的時(shí)候礁击,瀏覽器會(huì)自動(dòng)使用指定應(yīng)用程序來打開盐杂。多用于指定一些客戶端自定義的文件名逗载,以及一些媒體文件打開方式。

它是一個(gè)互聯(lián)網(wǎng)標(biāo)準(zhǔn)链烈,擴(kuò)展了電子郵件標(biāo)準(zhǔn)厉斟,使其能夠支持:

非ASCII字符文本;非文本格式附件(二進(jìn)制强衡、聲音擦秽、圖像等);由多部分(multiple parts)組成的消息體漩勤;包含非ASCII字符的頭信息(Header information)感挥。

這個(gè)標(biāo)準(zhǔn)被定義在RFC 2045、RFC 2046越败、RFC 2047触幼、RFC 2048、RFC 2049等RFC中究飞。 MIME改善了由RFC 822轉(zhuǎn)變而來的RFC 2822置谦,這些舊標(biāo)準(zhǔn)規(guī)定電子郵件標(biāo)準(zhǔn)并不允許在郵件消息中使用7位ASCII字符集以外的字符。正因如此亿傅,一些非英語字符消息和二進(jìn)制文件媒峡,圖像,聲音等非文字消息原本都不能在電子郵件中傳輸(MIME可以)葵擎。MIME規(guī)定了用于表示各種各樣的數(shù)據(jù)類型的符號(hào)化方法丝蹭。 此外,在萬維網(wǎng)中使用的HTTP協(xié)議中也使用了MIME的框架坪蚁,標(biāo)準(zhǔn)被擴(kuò)展為互聯(lián)網(wǎng)媒體類型奔穿。

查看不同文件對(duì)應(yīng)的 MIME 類型,推薦大家一種方式敏晤,以 Tomcat為例贱田,它下面的 web.xml 文件可以查看所有的MIME類型,通過 Ctrl + F 搜索快速找到你想知道的文件對(duì)應(yīng)的 MIME 類型嘴脾。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末男摧,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子译打,更是在濱河造成了極大的恐慌耗拓,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,496評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件奏司,死亡現(xiàn)場離奇詭異乔询,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)韵洋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門竿刁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來黄锤,“玉大人,你說我怎么就攤上這事食拜⊥沂欤” “怎么了?”我有些...
    開封第一講書人閱讀 162,632評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵负甸,是天一觀的道長流强。 經(jīng)常有香客問我,道長呻待,這世上最難降的妖魔是什么煮盼? 我笑而不...
    開封第一講書人閱讀 58,180評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮带污,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘香到。我一直安慰自己鱼冀,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評(píng)論 6 388
  • 文/花漫 我一把揭開白布悠就。 她就那樣靜靜地躺著千绪,像睡著了一般。 火紅的嫁衣襯著肌膚如雪梗脾。 梳的紋絲不亂的頭發(fā)上荸型,一...
    開封第一講書人閱讀 51,165評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音炸茧,去河邊找鬼瑞妇。 笑死,一個(gè)胖子當(dāng)著我的面吹牛梭冠,可吹牛的內(nèi)容都是我干的辕狰。 我是一名探鬼主播,決...
    沈念sama閱讀 40,052評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼控漠,長吁一口氣:“原來是場噩夢啊……” “哼蔓倍!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起盐捷,我...
    開封第一講書人閱讀 38,910評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤偶翅,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后碉渡,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體聚谁,經(jīng)...
    沈念sama閱讀 45,324評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評(píng)論 2 332
  • 正文 我和宋清朗相戀三年滞诺,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了垦巴。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片媳搪。...
    茶點(diǎn)故事閱讀 39,711評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖骤宣,靈堂內(nèi)的尸體忽然破棺而出秦爆,到底是詐尸還是另有隱情,我是刑警寧澤憔披,帶...
    沈念sama閱讀 35,424評(píng)論 5 343
  • 正文 年R本政府宣布等限,位于F島的核電站,受9級(jí)特大地震影響芬膝,放射性物質(zhì)發(fā)生泄漏望门。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評(píng)論 3 326
  • 文/蒙蒙 一锰霜、第九天 我趴在偏房一處隱蔽的房頂上張望筹误。 院中可真熱鬧,春花似錦癣缅、人聲如沸厨剪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽祷膳。三九已至,卻和暖如春屡立,著一層夾襖步出監(jiān)牢的瞬間直晨,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評(píng)論 1 269
  • 我被黑心中介騙來泰國打工膨俐, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留勇皇,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,722評(píng)論 2 368
  • 正文 我出身青樓焚刺,卻偏偏與公主長得像儒士,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子檩坚,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容