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

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

文件上傳的方式

  • Servlet2.5 方式

  • Servlet3.0 方式

  • SpringMVC 方式

案例實(shí)操

Servlet2.5 方式

文件上傳涉及到前臺頁面的編寫和后臺服務(wù)器端代碼的編寫,前臺發(fā)送文件战坤,后臺接收并保存文件曙强,這才是一個(gè)完整的文件上傳残拐。

1) 前臺頁面

在做文件上傳的時(shí)候,會有一個(gè)上傳文件的界面旗扑,首先我們需要一個(gè)表單蹦骑,并且表單的請求方式為 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ù)袱衷。

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="html" cid="n19" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>上傳文件</title>
</head>
<body>
<form action="uploadServlet" method="post" enctype="multipart/form-data">
文件:<input type="file" name="myfile"/>
<input type="submit" value="上傳" />
</form>
</body>
</html></pre>

2) 后臺 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è)工具包。

image

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

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

ServletFileUpload – 文件上傳的核心類,此類接收 request脱吱,并解析

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

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

2箱蝠、創(chuàng)建 ServletFileUpload 核心類续捂,接收臨時(shí)文件,做請求的轉(zhuǎn)換

3宦搬、通過 ServletFileUpload 類轉(zhuǎn)換原始請求牙瓢,得到 FileItem 集合

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

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

6、如果不是普通表單項(xiàng)憔足,則是文件聂渊,通過處理的方式進(jìn)行處理(上傳)

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="java" cid="n33" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">public class UploadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
?
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 設(shè)定編碼,可以獲取中文文件名
request.setCharacterEncoding("UTF-8");
// 獲取tomcat下的upload目錄的路徑
String path = getServletContext().getRealPath("/upload");
// 臨時(shí)文件目錄
String tempPath = getServletContext().getRealPath("/temp");
// 檢查我們是否有文件上傳請求
// boolean isMultipart = ServletFileUpload.isMultipartContent(req);
// 1四瘫、聲明DiskFileItemFactory工廠類,用于在指定磁盤上設(shè)置一個(gè)臨時(shí)目錄
DiskFileItemFactory disk = new DiskFileItemFactory(1024 * 10, new File(tempPath));
// 2欲逃、聲明ServletFileUpload找蜜,接收上面的臨時(shí)文件。也可以默認(rèn)值
ServletFileUpload up = new ServletFileUpload(disk);
// 3稳析、解析request
try {
List<FileItem> list = up.parseRequest(request);
if (list.size() > 0) {
for (FileItem file : list) {
// 判斷是否是普通的表單項(xiàng)
if (file.isFormField()) {
String fieldName = file.getFieldName();
// 中文亂碼洗做,此時(shí)還需要指定獲取數(shù)據(jù)的編碼方式
// String value = file.getString();
String value = file.getString("UTF-8");
System.out.println(fieldName + "=" + value);
} else { // 說明是一個(gè)文件
// 獲取文件本身的名稱
String fileName = file.getName();
System.out.println(file.getFieldName());
// 處理文件名稱
fileName = fileName.substring(fileName.lastIndexOf("\") + 1);
System.out.println("old Name : " + fileName);
// 修改名稱
String extName = fileName.substring(fileName.lastIndexOf("."));
String newName = UUID.randomUUID().toString().replace("-", "") + extName;
// 保存新的名稱弓叛,并寫出到新文件中
file.write(new File(path + "/" + newName));
System.out.println("文件名是:" + fileName);
System.out.println("文件大小是:" + file.getSize());
file.delete();
}
}
}
} catch (FileUploadException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
?
}</pre>

Servlet3.0 方式

使用注解 @MultipartConfig 將一個(gè) Servlet 標(biāo)識為支持文件上傳。Servlet3.0 將 multipart/form-data 的 POST 請求封裝成 Part诚纸,通過 Part 對上傳的文件進(jìn)行操作撰筷。

前臺

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="html" cid="n38" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>上傳文件</title>
</head>
<body>
<form action="upload" method="post" enctype="multipart/form-data">
姓名:<input type="text" name="uname"/>
文件:<input type="file" name="myfile"/>
<input type="submit" value="上傳" />
</form>
</body>
</html></pre>

后臺

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="java" cid="n40" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">@WebServlet("/upload")
@MultipartConfig
public class UploadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
?
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("上傳文件...");
// 設(shè)置編碼
request.setCharacterEncoding("UTF-8");
// 獲取普通表單項(xiàng)參數(shù)
String uname = request.getParameter("uname");
System.out.println(uname);
// 上傳文件
// 得到part對象 request.getpart(name):name代表的是表單中file元素的name屬性值
Part part = request.getPart("myfile");
// 得到文件存放的路徑
String path = request.getServletContext().getRealPath("/");
// 得到文件名
String fileName = part.getSubmittedFileName();
// 上傳
part.write(path + fileName);
}
?
}</pre>

SpringMVC 方式

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

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="xml" cid="n44" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><dependency>
?
<groupId>commons-fileupload</groupId>
?
<artifactId>commons-fileupload</artifactId>
?
<version>1.3.2</version>
?
</dependency> </pre>

servlet-context.xml

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="xml" cid="n46" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
?
<property name="maxUploadSize">
?
<value>104857600</value>
?
</property>
?
<property name="maxInMemorySize">
?
<value>4096</value>
?
</property>
?
</bean> </pre>

FileController

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="java" cid="n48" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">import java.io.File;
?
import java.io.IOException;
?
import javax.servlet.http.HttpServletRequest;
?
import org.springframework.stereotype.Controller;
?
import org.springframework.web.bind.annotation.RequestMapping;
?
import org.springframework.web.multipart.MultipartFile;
?
import org.springframework.web.multipart.MultipartHttpServletRequest;
?
import org.springframework.web.servlet.ModelAndView;
?
@Controller
?
public class FileController {
?
@RequestMapping("/uploadFile")
?
public ModelAndView uploadFile(HttpServletRequest request){
?
ModelAndView mv=new ModelAndView();
?
mv.setViewName("result");
?
MultipartHttpServletRequest mr=(MultipartHttpServletRequest) request;
?
MultipartFile multipartFile= mr.getFile("file");
?
String path=request.getSession().getServletContext().getRealPath("upload");
?
System.out.println(path);
?
if(null!=multipartFile&&!multipartFile.isEmpty()){
?
String fileName=multipartFile.getOriginalFilename();
?
try {
?
multipartFile.transferTo(new File(path,fileName));
?
mv.addObject("msg", "文件上傳成功!");
?
} catch (Exception e) {
?
mv.addObject("msg", "上傳失敗!");
?
e.printStackTrace();
?
}
?
}
?
return mv;
?
}
?
} </pre>

前臺表單

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="jsp" cid="n50" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><form action="uploadFile" method="post" enctype="multipart/form-data">
?
<input type="file" name="file"/>
?
<button type="submit"> 提交</button>
?
</form> </pre>

擴(kuò)展~MIME

MIME(Multipurpose Internet Mail Extensions)多用途互聯(lián)網(wǎng)郵件擴(kuò)展類型。是設(shè)定某種擴(kuò)展名的文件用一種應(yīng)用程序來打開的方式類型畦徘,當(dāng)該擴(kuò)展名文件被訪問的時(shí)候毕籽,瀏覽器會自動使用指定應(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ù)類型的符號化方法檀头。 此外轰异,在萬維網(wǎng)中使用的HTTP協(xié)議中也使用了MIME的框架,標(biāo)準(zhǔn)被擴(kuò)展為互聯(lián)網(wǎng)媒體類型暑始。

查看不同文件對應(yīng)的 MIME 類型搭独,推薦大家一種方式,以 Tomcat為例廊镜,它下面的 web.xml 文件可以查看所有的MIME類型牙肝,通過 Ctrl + F 搜索快速找到你想知道的文件對應(yīng)的 MIME 類型。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市配椭,隨后出現(xiàn)的幾起案子虫溜,更是在濱河造成了極大的恐慌,老刑警劉巖股缸,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件衡楞,死亡現(xiàn)場離奇詭異,居然都是意外死亡敦姻,警方通過查閱死者的電腦和手機(jī)瘾境,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來替劈,“玉大人寄雀,你說我怎么就攤上這事≡上祝” “怎么了盒犹?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長眨业。 經(jīng)常有香客問我急膀,道長,這世上最難降的妖魔是什么龄捡? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任卓嫂,我火速辦了婚禮,結(jié)果婚禮上聘殖,老公的妹妹穿的比我還像新娘晨雳。我一直安慰自己,他們只是感情好奸腺,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布餐禁。 她就那樣靜靜地躺著,像睡著了一般突照。 火紅的嫁衣襯著肌膚如雪帮非。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天讹蘑,我揣著相機(jī)與錄音末盔,去河邊找鬼。 笑死座慰,一個(gè)胖子當(dāng)著我的面吹牛陨舱,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播版仔,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼隅忿,長吁一口氣:“原來是場噩夢啊……” “哼心剥!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起背桐,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蝉揍,沒想到半個(gè)月后链峭,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡又沾,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年弊仪,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片杖刷。...
    茶點(diǎn)故事閱讀 40,040評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡励饵,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出滑燃,到底是詐尸還是另有隱情役听,我是刑警寧澤,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布表窘,位于F島的核電站典予,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏乐严。R本人自食惡果不足惜瘤袖,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望昂验。 院中可真熱鬧捂敌,春花似錦、人聲如沸既琴。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽呛梆。三九已至锐涯,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間填物,已是汗流浹背纹腌。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留滞磺,地道東北人升薯。 一個(gè)月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像击困,于是被迫代替她去往敵國和親涎劈。 傳聞我的和親對象是個(gè)殘疾皇子广凸,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評論 2 355