SpringMVC單文件上傳與多文件上傳

一枣氧、簡述

一個javaWeb項(xiàng)目中网缝,文件上傳功能幾乎是必不可少的,本人在項(xiàng)目開發(fā)中也時常會遇到疫稿,以前也沒怎么去理它培他,今天有空學(xué)習(xí)了一下這方面的知識,于是便將本人學(xué)到的SpringMVC中單文件與多文件上傳這部分知識做下筆記遗座。

二舀凛、單文件上傳

1、頁面

這里以一個簡單的表單提交為例子途蒋,文件上傳需要將表單的提交方法設(shè)置為post猛遍,將enctype的值設(shè)置為"multipart/form-data"。

<form action="${pageContext.request.contextPath}/test/upload.do" method="post" enctype="multipart/form-data">
    <input type="file" name="img"><br /> 
    <input type="submit" name="提交">
</form>

2号坡、控制器

在Controller的處理方法中懊烤,使用MultipartFile對象作為參數(shù)接收前端上傳過來的文件,具體說明請看代碼注釋宽堆。

@Controller
@RequestMapping("/test")
public class MyController {

    @RequestMapping(value = "/upload.do", method = RequestMethod.POST)
    // 這里的MultipartFile對象變量名跟表單中的file類型的input標(biāo)簽的name相同腌紧,所以框架會自動用MultipartFile對象來接收上傳過來的文件,當(dāng)然也可以使用@RequestParam("img")指定其對應(yīng)的參數(shù)名稱
    public String upload(MultipartFile img, HttpSession session)
            throws Exception {
        // 如果沒有文件上傳畜隶,MultipartFile也不會為null壁肋,可以通過調(diào)用getSize()方法獲取文件的大小來判斷是否有上傳文件
        if (img.getSize() > 0) {
            // 得到項(xiàng)目在服務(wù)器的真實(shí)根路徑,如:/home/tomcat/webapp/項(xiàng)目名/images
            String path = session.getServletContext().getRealPath("images");
            // 得到文件的原始名稱籽慢,如:美女.png
            String fileName = img.getOriginalFilename();
            // 通過文件的原始名稱浸遗,可以對上傳文件類型做限制,如:只能上傳jpg和png的圖片文件
            if (fileName.endsWith("jpg") || fileName.endsWith("png")) {
                File file = new File(path, fileName);
                img.transferTo(file);
                return "/success.jsp";
            }
        }
        return "/error.jsp";
    }
}

3箱亿、springmvc.xml配置

使用MultipartFile對象接收前端上傳過來的文件跛锌,還需要在springmvc的配置文件中進(jìn)行如下配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    ...
    
    <!-- 注意:CommonsMultipartResolver的id是固定不變的,一定是multipartResolver极景,不可修改 -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!-- 如果上傳后出現(xiàn)文件名中文亂碼可以使用該屬性解決 -->
        <property name="defaultEncoding" value="utf-8"/>
        <!-- 單位是字節(jié)察净,不設(shè)置默認(rèn)不限制總的上傳文件大小,這里設(shè)置總的上傳文件大小不超過1M(1*1024*1024) -->
        <property name="maxUploadSize" value="1048576"/>
        <!-- 跟maxUploadSize差不多盼樟,不過maxUploadSizePerFile是限制每個上傳文件的大小氢卡,而maxUploadSize是限制總的上傳文件大小 -->
        <property name="maxUploadSizePerFile" value="1048576"/>
    </bean>
    
    <!-- 設(shè)置一個簡單的異常解析器,當(dāng)文件上傳超過大小限制時跳轉(zhuǎn) -->
    <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
        <property name="defaultErrorView" value="/error.jsp"/>
    </bean>
</beans>

上面配置文件中的CommonsMultipartResolver下的屬性值配置不是必須的晨缴,你也可以全部不寫译秦。到這里就可以實(shí)現(xiàn)單個文件上傳了,下面來看看多文件上傳。

三筑悴、多文件上傳

其實(shí)多文件上傳也很簡單们拙,單文件上傳是在Controller的處理方法中使用MultipartFile對象作為參數(shù)接收前端上傳過來的文件,而多文件上傳則使用MultipartFile對象數(shù)組來接收阁吝。

1砚婆、頁面

該頁面中有幾個name值一樣的file類型的input標(biāo)簽,其他跟單文件上傳的頁面沒差突勇。

<form action="${pageContext.request.contextPath}/test/upload.do" method="post" enctype="multipart/form-data">
    file 1 : <input type="file" name="imgs"><br /> 
    file 2 : <input type="file" name="imgs"><br /> 
    file 3 : <input type="file" name="imgs"><br /> 
    <input type="submit" name="提交">
</form>

2装盯、控制器

控制器中的處理方法使用MultipartFile[]數(shù)組作為接收參數(shù),并不能直接使用甲馋,需要校正參數(shù)埂奈,具體說明請看代碼注釋。

@Controller
@RequestMapping("/test")
public class MyController {

    @RequestMapping(value = "/upload.do", method = RequestMethod.POST)
    // 這里的MultipartFile[] imgs表示前端頁面上傳過來的多個文件定躏,imgs對應(yīng)頁面中多個file類型的input標(biāo)簽的name账磺,但框架只會將一個文件封裝進(jìn)一個MultipartFile對象,
    // 并不會將多個文件封裝進(jìn)一個MultipartFile[]數(shù)組痊远,直接使用會報(bào)[Lorg.springframework.web.multipart.MultipartFile;.<init>()錯誤垮抗,
    // 所以需要用@RequestParam校正參數(shù)(參數(shù)名與MultipartFile對象名一致),當(dāng)然也可以這么寫:@RequestParam("imgs") MultipartFile[] files碧聪。
    public String upload(@RequestParam MultipartFile[] imgs, HttpSession session)
            throws Exception {
        for (MultipartFile img : imgs) {
            if (img.getSize() > 0) {
                String path = session.getServletContext().getRealPath("images");
                String fileName = img.getOriginalFilename();
                if (fileName.endsWith("jpg") || fileName.endsWith("png")) {
                    File file = new File(path, fileName);
                    img.transferTo(file);
                }
            }
        }
        return "/success.jsp";
    }
}

同樣的借宵,使用MultipartFile數(shù)組接收前端上傳過來的多個文件,也需要在springmvc的配置文件進(jìn)行配置矾削,具體配置與上述單文件上傳的springmvc.xml配置沒差,直接拷貝過來就行豁护。這樣哼凯,就可以進(jìn)行多文件上傳了。

四楚里、多種文件上傳情景綜合

當(dāng)然断部,項(xiàng)目開發(fā)中,場景可能并不是這么簡單班缎,上述的多文件上傳是一個個文件選擇后一起上傳(即多個name相同的input標(biāo)簽)蝴光,那要是我項(xiàng)目中只要一個input標(biāo)簽就可以一次性多個文件呢?又或者一個頁面中既要一個個選擇的多文件上傳达址,又要一次性選擇的多文件上傳蔑祟,還要有單文件上傳呢?沒問題沉唠,MultipartFile[]通吃疆虚,代碼也很easy,下面直接上代碼。

1径簿、頁面

這里的 “一次選擇多個文件的多文件上傳” 只是在input標(biāo)簽中加上了multiple屬性而已罢屈。

<form action="${pageContext.request.contextPath}/test/upload.do" method="post" enctype="multipart/form-data">

    一次選擇多個文件的多文件上傳 : <br /> 
    <input type="file" name="imgs1" multiple><br /> <br /> 

    一次選擇一個文件的多文件上傳 : <br /> 
    <input type="file" name="imgs2"><br /> 
    <input type="file" name="imgs2"><br /><br /> 

    單文件上傳 : <br /> 
    <input type="file" name="imgs3"><br /><br /> 
    <input type="submit" name="提交">
</form>

2、控制器

@Controller
@RequestMapping("/test")
public class MyController {

    @RequestMapping(value = "/upload.do", method = RequestMethod.POST)
    public String upload(@RequestParam MultipartFile[] imgs1,@RequestParam MultipartFile[] imgs2,@RequestParam MultipartFile[] imgs3, HttpSession session)
            throws Exception {
        String path = session.getServletContext().getRealPath("images");
        for (MultipartFile img : imgs1) {
            uploadFile(path, img);
        }
        for (MultipartFile img : imgs2) {
            uploadFile(path, img);
        }
        for (MultipartFile img : imgs3) {
            uploadFile(path, img);
        }
        return "/success.jsp";
    }

    private void uploadFile(String path, MultipartFile img) throws IOException {
        if (img.getSize() > 0) {
            String fileName = img.getOriginalFilename();
            if (fileName.endsWith("jpg") || fileName.endsWith("png")) {
                File file = new File(path, fileName);
                img.transferTo(file);
            }
        }
    }
}

MultipartFile[]就是如此強(qiáng)大篇亭,不管單個多個缠捌,邏輯處理一樣,所以建議在項(xiàng)目開發(fā)中使用MultipartFile[]作為文件的接收參數(shù)译蒂。

五曼月、拓展

1、MultipartFile類常用的一些方法:

String getContentType()//獲取文件MIME類型
InputStream getInputStream()//獲取文件流
String getName() //獲取表單中文件組件的名字
String getOriginalFilename() //獲取上傳文件的原名
long getSize()  //獲取文件的字節(jié)大小蹂随,單位byte
boolean isEmpty() //是否為空
void transferTo(File dest) 

2十嘿、CommonsMultipartResolver的屬性解析

defaultEncoding:表示用來解析request請求的默認(rèn)編碼格式,當(dāng)沒有指定的時候根據(jù)Servlet規(guī)范會使用默認(rèn)值ISO-8859-1岳锁。當(dāng)request自己指明了它的編碼格式的時候就會忽略這里指定的defaultEncoding绩衷。
uploadTempDir:設(shè)置上傳文件時的臨時目錄,默認(rèn)是Servlet容器的臨時目錄激率。
maxUploadSize:設(shè)置允許上傳的總的最大文件大小咳燕,以字節(jié)為單位計(jì)算。當(dāng)設(shè)為-1時表示無限制乒躺,默認(rèn)是-1招盲。
maxUploadSizePerFile:跟maxUploadSize差不多,不過maxUploadSizePerFile是限制每個上傳文件的大小嘉冒,而maxUploadSize是限制總的上傳文件大小曹货。
maxInMemorySize:設(shè)置在文件上傳時允許寫到內(nèi)存中的最大值,以字節(jié)為單位計(jì)算讳推,默認(rèn)是10240顶籽。
resolveLazily:為true時,啟用推遲文件解析银觅,以便在UploadAction中捕獲文件大小異常礼饱。

六、注意

  1. 在開發(fā)過程中究驴,建議把配置文件中的異常解析器(SimpleMappingExceptionResolver)先注釋掉镊绪,方便我們查看錯誤。
  2. 有時候上傳出錯洒忧,是因?yàn)槲覀冊谂渲梦募邢拗屏松蟼魑募拇笮『拢憧梢圆患舆@個限制,但個人建議這個限制最好還是加上跑慕,具體文件大小限制請根據(jù)公司項(xiàng)目情況而定万皿。
  3. SpringMVC中使用MultipartFile接收上傳文件需要依賴兩個jar包摧找,分別是:commons-fileupload-1.3.3.jar、commons-io-2.5.jar牢硅。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蹬耘,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子减余,更是在濱河造成了極大的恐慌综苔,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,820評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件位岔,死亡現(xiàn)場離奇詭異如筛,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)抒抬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評論 3 399
  • 文/潘曉璐 我一進(jìn)店門杨刨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人擦剑,你說我怎么就攤上這事妖胀。” “怎么了惠勒?”我有些...
    開封第一講書人閱讀 168,324評論 0 360
  • 文/不壞的土叔 我叫張陵赚抡,是天一觀的道長。 經(jīng)常有香客問我纠屋,道長涂臣,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,714評論 1 297
  • 正文 為了忘掉前任售担,我火速辦了婚禮赁遗,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘族铆。我一直安慰自己吼和,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,724評論 6 397
  • 文/花漫 我一把揭開白布骑素。 她就那樣靜靜地躺著,像睡著了一般刚夺。 火紅的嫁衣襯著肌膚如雪献丑。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,328評論 1 310
  • 那天侠姑,我揣著相機(jī)與錄音创橄,去河邊找鬼。 笑死莽红,一個胖子當(dāng)著我的面吹牛妥畏,可吹牛的內(nèi)容都是我干的邦邦。 我是一名探鬼主播,決...
    沈念sama閱讀 40,897評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼醉蚁,長吁一口氣:“原來是場噩夢啊……” “哼燃辖!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起网棍,我...
    開封第一講書人閱讀 39,804評論 0 276
  • 序言:老撾萬榮一對情侶失蹤黔龟,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后滥玷,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體氏身,經(jīng)...
    沈念sama閱讀 46,345評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,431評論 3 340
  • 正文 我和宋清朗相戀三年惑畴,在試婚紗的時候發(fā)現(xiàn)自己被綠了蛋欣。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,561評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡如贷,死狀恐怖陷虎,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情倒得,我是刑警寧澤泻红,帶...
    沈念sama閱讀 36,238評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站霞掺,受9級特大地震影響谊路,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜菩彬,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,928評論 3 334
  • 文/蒙蒙 一缠劝、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧骗灶,春花似錦惨恭、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至免都,卻和暖如春锉罐,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背绕娘。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評論 1 272
  • 我被黑心中介騙來泰國打工脓规, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人险领。 一個月前我還...
    沈念sama閱讀 48,983評論 3 376
  • 正文 我出身青樓侨舆,卻偏偏與公主長得像秒紧,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子挨下,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,573評論 2 359

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理熔恢,服務(wù)發(fā)現(xiàn),斷路器复颈,智...
    卡卡羅2017閱讀 134,702評論 18 139
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,290評論 25 707
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,855評論 6 342
  • 因?yàn)楸容^喜歡吃日式豬排飯绩聘,所以就自己試著做了,自己做的時候特意弄得清淡了很多耗啦,也是另一種不同的風(fēng)格啊凿菩。 用料: 超...
    悠然小蝦閱讀 429評論 0 4
  • 開場秀之后衅谷,就是主題了。這是第一周的第二篇似将,還是一如既往的流水日志获黔。 每周二篇文章,不限主題題材和字?jǐn)?shù)在验,看似不多也...
    魚塘沒有魚閱讀 285評論 0 0