一、簡(jiǎn)述
multipart格式的數(shù)據(jù)會(huì)將一個(gè)表單拆分為多個(gè)部分(part),每個(gè)部分對(duì)應(yīng)一個(gè)輸入域。在一般的表單輸入域中,它所對(duì)應(yīng)的部分中會(huì)放置文本型數(shù)據(jù),但是如果上傳文件的話,它所對(duì)應(yīng)的部分可以是二進(jìn)制。類似這樣:
二、 配置 multipart 解析器
盡管multipart請(qǐng)求看起來(lái)很復(fù)雜,但在spring mvc中處理它們卻很容易。在編寫控制器方法處理文件上傳之前,我們必須要配置一個(gè)multipart解析器,通過(guò)它來(lái)告訴dispatcherservlet該如何讀取multipart請(qǐng)求。
spring 內(nèi)置了兩個(gè)multipartresolver的實(shí)現(xiàn):
-
commonsmultipartresolver :使用jakarta commons fileupload解析multipart請(qǐng)求;
-
standardservletmultipartresolver :依賴于servlet 3.0對(duì)multipart請(qǐng)求的支持(始于spring 3.1)。
standardservletmultipartresolver的配置:
1、聲明bean:
在applicationcontext.xml 配置
在配置類中配置
1
2
3
4
|
@bean (name = "multipartresolver" ) public standardservletmultipartresolver getstandardservletmultipartresolver(){ return new standardservletmultipartresolver(); } |
tips:multipart解析器的命名一定要是 multipartresolver ,否則會(huì)報(bào)錯(cuò)。
2、配置上傳參數(shù):
* web.xml 配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
<servlet> <servlet-name>dispatcherservlet</servlet-name> <servlet- class >org.springframework.web.servlet.dispatcherservlet</servlet- class > <init-param> <param-name>contextconfiglocation</param-name> <param-value>classpath:applicationcontext.xml</param-value> </init-param> <load-on-startup> 1 </load-on-startup> <multipart-config> <!--上傳到/tmp/upload 目錄--> <location>/tmp/upload</location> <!--文件大小為2m--> <max-file-size> 2097152 </max-file-size> <!--整個(gè)請(qǐng)求不超過(guò)4m--> <max-request-size> 4194304 </max-request-size> <!--所有文件都要寫入磁盤--> <file-size-threshold> 0 </file-size-threshold> </multipart-config> </servlet> <servlet-mapping> <servlet-name>dispatcherservlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> |
* 配置類中配置
繼承 abstractannotationconfigdispatcherservletinitializer 的配置類
1
2
3
4
5
|
@override protected void customizeregistration(servletregistration.dynamic registration) { //上傳到/tmp/upload 目錄,文件大小為2m,整個(gè)請(qǐng)求不超過(guò)4m,而且所有文件都要寫入磁盤 registration.setmultipartconfig( new multipartconfigelement( "e:\\upload_ftp" , 2097152 , 4194304 , 0 )); } |
commonsmultipartresolver的配置:
1、聲明bean 和 配置上傳參數(shù)
1
2
3
4
5
6
|
<bean id= "multipartresolver" class = "org.springframework.web.multipart.commons.commonsmultipartresolver" > <!--設(shè)置上傳目錄/tmp/upload;最大的文件容量設(shè)置為2m;最大的內(nèi)存大小設(shè)置為 0 ,表示所有文件都會(huì)寫入磁盤中;無(wú)法設(shè)定multipart請(qǐng)求整體的最大容量--> <property name= "uploadtempdir" value= "/tmp/upload" /> <property name= "maxuploadsize" value= "2097152" /> <property name= "maxinmemorysize" value= "0" /> </bean> |
區(qū)別:
1、 commonsmultipartresolver 相比較 standardservletmultipartresolver 來(lái)說(shuō) 就是無(wú)法設(shè)定multipart請(qǐng)求整體的最大容量。
2、 commonsmultipartresolver 不會(huì)強(qiáng)制要求設(shè)置臨時(shí)文件路徑。默認(rèn)情況下,這個(gè)路徑就是 servlet 容器的臨時(shí)目錄。 standardservletmultipartresolver 必須設(shè)置臨時(shí)文件路徑才能正常執(zhí)行。(以上所述上傳目錄均為臨時(shí)文件路徑)
三、springmvc 處理請(qǐng)求
1、前端form 表單
1
2
3
4
|
<form action= "/picture" method= "post" enctype= "multipart/form-data" > <input type= "file" name= "picture" > <input type= "submit" > </form> |
tips:需要設(shè)置 enctype="multipart/form-data",以告訴springmvc 這是一個(gè)multipart 請(qǐng)求。
2、后端mvc接受請(qǐng)求
1
2
3
4
5
6
7
8
|
@requestmapping (value = "/picture" ,method = requestmethod.post) public string gethome( @requestpart ( "picture" ) multipartfile picture) throws ioexception { string name = picture.getname(); byte [] bytes = picture.getbytes(); picture.transferto( new file( "/" +picture.getoriginalfilename())); //這里保存到文件系統(tǒng)的時(shí)候要用相對(duì)路徑,比如這里配置的是 /。以配置的上傳目錄為基準(zhǔn)。即文件路徑 e:/upload_ftp/ 是保存的目錄 return "home" ; } |
tips:1、@requestpart("picture") : 當(dāng)注冊(cè)表單提交的時(shí)候,p icture 屬性將會(huì)給定一個(gè) byte 數(shù)組,這個(gè)數(shù)組中包含了請(qǐng)求中對(duì)應(yīng) part 的數(shù)據(jù)(通過(guò) @requestpart 指定)。如果用戶提交表單的時(shí)候沒(méi)有選擇文件,那么這個(gè)數(shù)組會(huì)是空(而不是 null )。所以說(shuō)我們甚至可以用byte[]數(shù)組接收multipart請(qǐng)求而不用 multipartfile。
2、multipartfile :用multipartfile方法接收為我們提供了很多的方法以便進(jìn)行接下來(lái)的工作...
3、 以 part的形式接受上傳的文件
就主體來(lái)言, part 接口與 multipartfile 并沒(méi)有太大的差別。 在很多情況下, part 方法的名稱與 multipartfile 方法的名稱是完全相同的。有一些比較類似,但是稍有差異,比如 getsubmittedfilename() 對(duì)應(yīng)于 getoriginalfilename() 。類似地, write() 對(duì)應(yīng)于 transferto() ,借助該方法我們能夠?qū)⑸蟼鞯奈募懭胛募到y(tǒng)中。
值得一提的是,如果在編寫控制器方法的時(shí)候,通過(guò)part參數(shù)的形式接受文件上傳,那么就沒(méi)有必要設(shè)置multipartresolver 了。只有使用multipartfile的時(shí)候,我們才需要multipartresolver。
1
2
3
4
5
|
@requestmapping (value = "/picture" ,method = requestmethod.post) public string gethome( @requestpart ( "picture" ) part picture) throws ioexception { picture.write( "/" +picture.getsubmittedfilename()); return "home" ; } |
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。
原文鏈接:http://www.cnblogs.com/jmcui/p/8179174.html