java 文件上傳(單文件與多文件)
java 文件上傳(單文件與多文件)
一、簡(jiǎn)述
一個(gè)javaWeb項(xiàng)目中,文件上傳功能幾乎是必不可少的,本人在項(xiàng)目開(kāi)發(fā)中也時(shí)常會(huì)遇到,以前也沒(méi)怎么去理它,今天有空學(xué)習(xí)了一下這方面的知識(shí),于是便將本人學(xué)到的SpringMVC中單文件與多文件上傳這部分知識(shí)做下筆記。
二、單文件上傳
1、頁(yè)面
這里以一個(gè)簡(jiǎn)單的表單提交為例子,文件上傳需要將表單的提交方法設(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對(duì)象作為參數(shù)接收前端上傳過(guò)來(lái)的文件,具體說(shuō)明請(qǐng)看代碼注釋。
@Controller
@RequestMapping("/test")
public class MyController {
@RequestMapping(value = "/upload.do", method = RequestMethod.POST)
// 這里的MultipartFile對(duì)象變量名跟表單中的file類型的input標(biāo)簽的name相同,所以框架會(huì)自動(dòng)用MultipartFile對(duì)象來(lái)接收上傳過(guò)來(lái)的文件,當(dāng)然也可以使用@RequestParam("img")指定其對(duì)應(yīng)的參數(shù)名稱
public String upload(MultipartFile img, HttpSession session)
throws Exception {
// 如果沒(méi)有文件上傳,MultipartFile也不會(huì)為null,可以通過(guò)調(diào)用getSize()方法獲取文件的大小來(lái)判斷是否有上傳文件
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();
// 通過(guò)文件的原始名稱,可以對(duì)上傳文件類型做限制,如:只能上傳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對(duì)象接收前端上傳過(guò)來(lái)的文件,還需要在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è)置總的上傳文件大小不超過(guò)1M(1*1024*1024) -->
<property name="maxUploadSize" value="1048576"/>
<!-- 跟maxUploadSize差不多,不過(guò)maxUploadSizePerFile是限制每個(gè)上傳文件的大小,而maxUploadSize是限制總的上傳文件大小 -->
<property name="maxUploadSizePerFile" value="1048576"/>
</bean>
<!-- 設(shè)置一個(gè)簡(jiǎn)單的異常解析器,當(dāng)文件上傳超過(guò)大小限制時(shí)跳轉(zhuǎn) -->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="defaultErrorView" value="/error.jsp"/>
</bean>
</beans>
上面配置文件中的CommonsMultipartResolver下的屬性值配置不是必須的,你也可以全部不寫(xiě)。到這里就可以實(shí)現(xiàn)單個(gè)文件上傳了,下面來(lái)看看多文件上傳。
三、多文件上傳
其實(shí)多文件上傳也很簡(jiǎn)單,單文件上傳是在Controller的處理方法中使用MultipartFile對(duì)象作為參數(shù)接收前端上傳過(guò)來(lái)的文件,而多文件上傳則使用MultipartFile對(duì)象數(shù)組來(lái)接收。
1、頁(yè)面
該頁(yè)面中有幾個(gè)name值一樣的file類型的input標(biāo)簽,其他跟單文件上傳的頁(yè)面沒(méi)差。
<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ù),具體說(shuō)明請(qǐng)看代碼注釋。
@Controller
@RequestMapping("/test")
public class MyController {
@RequestMapping(value = "/upload.do", method = RequestMethod.POST)
// 這里的MultipartFile[] imgs表示前端頁(yè)面上傳過(guò)來(lái)的多個(gè)文件,imgs對(duì)應(yīng)頁(yè)面中多個(gè)file類型的input標(biāo)簽的name,但框架只會(huì)將一個(gè)文件封裝進(jìn)一個(gè)MultipartFile對(duì)象,
// 并不會(huì)將多個(gè)文件封裝進(jìn)一個(gè)MultipartFile[]數(shù)組,直接使用會(huì)報(bào)[Lorg.springframework.web.multipart.MultipartFile;.<init>()錯(cuò)誤,
// 所以需要用@RequestParam校正參數(shù)(參數(shù)名與MultipartFile對(duì)象名一致),當(dāng)然也可以這么寫(xiě):@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ù)組接收前端上傳過(guò)來(lái)的多個(gè)文件,也需要在springmvc的配置文件進(jìn)行配置,具體配置與上述單文件上傳的springmvc.xml配置沒(méi)差,直接拷貝過(guò)來(lái)就行。這樣,就可以進(jìn)行多文件上傳了。
四、多種文件上傳情景綜合
當(dāng)然,項(xiàng)目開(kāi)發(fā)中,場(chǎng)景可能并不是這么簡(jiǎn)單,上述的多文件上傳是一個(gè)個(gè)文件選擇后一起上傳(即多個(gè)name相同的input標(biāo)簽),那要是我項(xiàng)目中只要一個(gè)input標(biāo)簽就可以一次性多個(gè)文件呢?又或者一個(gè)頁(yè)面中既要一個(gè)個(gè)選擇的多文件上傳,又要一次性選擇的多文件上傳,還要有單文件上傳呢?沒(méi)問(wèn)題,MultipartFile[]通吃,代碼也很easy,下面直接上代碼。
1、頁(yè)面
這里的 “一次選擇多個(gè)文件的多文件上傳” 只是在input標(biāo)簽中加上了multiple屬性而已。
<form action="${pageContext.request.contextPath}/test/upload.do" method="post" enctype="multipart/form-data">
一次選擇多個(gè)文件的多文件上傳 : <br />
<input type="file" name="imgs1" multiple><br /> <br />
一次選擇一個(gè)文件的多文件上傳 : <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)大,不管單個(gè)多個(gè),邏輯處理一樣,所以建議在項(xiàng)目開(kāi)發(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:表示用來(lái)解析request請(qǐng)求的默認(rèn)編碼格式,當(dāng)沒(méi)有指定的時(shí)候根據(jù)Servlet規(guī)范會(huì)使用默認(rèn)值ISO-8859-1。當(dāng)request自己指明了它的編碼格式的時(shí)候就會(huì)忽略這里指定的defaultEncoding。 uploadTempDir:設(shè)置上傳文件時(shí)的臨時(shí)目錄,默認(rèn)是Servlet容器的臨時(shí)目錄。 maxUploadSize:設(shè)置允許上傳的總的最大文件大小,以字節(jié)為單位計(jì)算。當(dāng)設(shè)為-1時(shí)表示無(wú)限制,默認(rèn)是-1。 maxUploadSizePerFile:跟maxUploadSize差不多,不過(guò)maxUploadSizePerFile是限制每個(gè)上傳文件的大小,而maxUploadSize是限制總的上傳文件大小。 maxInMemorySize:設(shè)置在文件上傳時(shí)允許寫(xiě)到內(nèi)存中的最大值,以字節(jié)為單位計(jì)算,默認(rèn)是10240。 resolveLazily:為true時(shí),啟用推遲文件解析,以便在UploadAction中捕獲文件大小異常。
六、注意
- 在開(kāi)發(fā)過(guò)程中,建議把配置文件中的異常解析器(SimpleMappingExceptionResolver)先注釋掉,方便我們查看錯(cuò)誤。
- 有時(shí)候上傳出錯(cuò),是因?yàn)槲覀冊(cè)谂渲梦募邢拗屏松蟼魑募拇笮。憧梢圆患舆@個(gè)限制,但個(gè)人建議這個(gè)限制最好還是加上,具體文件大小限制請(qǐng)根據(jù)公司項(xiàng)目情況而定。
- SpringMVC中使用MultipartFile接收上傳文件需要依賴兩個(gè)jar包,分別是:commons-fileupload-1.3.3.jar、commons-io-2.5.jar。
如有疑問(wèn)請(qǐng)留言或者到本站社區(qū)交流討論,感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
相關(guān)文章
Java中提供synchronized后為什么還要提供Lock
這篇文章主要介紹了Java中提供synchronized后為什么還要提供Lock,在Java中提供了synchronized關(guān)鍵字來(lái)保證只有一個(gè)線程能夠訪問(wèn)同步代碼塊,下文更多相關(guān)資料需要的小伙伴可以參考一下2022-03-03
springboot開(kāi)發(fā)擴(kuò)展springmvc實(shí)現(xiàn)解析
這篇文章主要介紹了springboot開(kāi)發(fā)擴(kuò)展springmvc實(shí)現(xiàn)解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-02-02
java隨機(jī)抽取指定范圍不重復(fù)的數(shù)字
這篇文章主要介紹了java隨機(jī)抽取指定范圍不重復(fù)的數(shù)字的相關(guān)資料,需要的朋友可以參考下2016-06-06
利用logback filter過(guò)濾某個(gè)類 屏蔽某個(gè)類
這篇文章主要介紹了利用logback filter過(guò)濾某個(gè)類 屏蔽某個(gè)類的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07
SpringSecurity授權(quán)機(jī)制的實(shí)現(xiàn)(AccessDecisionManager與投票決策)
本文主要介紹了SpringSecurity授權(quán)機(jī)制的實(shí)現(xiàn),其核心是AccessDecisionManager和投票系統(tǒng),下面就來(lái)介紹一下,感興趣的可以了解一下2025-04-04
WMTS中TileMatrix與ScaleDenominator淺析
這篇文章主要為大家介紹了WMTS中TileMatrix與ScaleDenominator淺析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03
idea運(yùn)行vue項(xiàng)目設(shè)置自定義瀏覽器方式
這篇文章主要介紹了idea運(yùn)行vue項(xiàng)目設(shè)置自定義瀏覽器方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-08-08
JPA?通過(guò)Specification如何實(shí)現(xiàn)復(fù)雜查詢
這篇文章主要介紹了JPA?通過(guò)Specification如何實(shí)現(xiàn)復(fù)雜查詢,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11
Java使用BigDecimal精確運(yùn)算浮點(diǎn)數(shù)
這篇文章主要介紹了Java使用BigDecimal精確運(yùn)算浮點(diǎn)數(shù),幫助大家更好的處理浮點(diǎn)數(shù)數(shù)據(jù),感興趣的朋友可以了解下2020-10-10
java.lang.ClassCastException的問(wèn)題解決
本文主要介紹了java.lang.ClassCastException的問(wèn)題解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-06-06

