文件上傳應該大部分人都接觸過,通常都是基於commons-fileupload組件來實現,SpringMVC的文件上傳功能也是在commons-fileupload組件提供的功能上面作了一些包裝功能,使文件上傳開發更容易方便。java
看下上傳效果圖:mysql
項目運行效果:git
項目源碼地址,發佈便可用:https://github.com/wuskyfantasy/fileupload.sys github
項目使用spring mvc+mybatis實現,數據庫採用mysql,具體參考README就能夠發佈起來。web
1、實現普通文件上傳spring
咱們知道,類DispatcherServlet是SpringMVC的入口,在其doDispatch方法裏面,咱們能夠看到它會先去檢查有沒配置multipartResolver
若是有的話會先執行它的resolveMultipart方法:
所以,咱們在配置文件中添加: 則可以使用SpringMVC自帶的CommonsMultipartResolver實現多個文件上傳的功能。sql
2、實現進度條
如今實現帶進度條的文件上傳通常都是在客戶端用flash上傳組件計算,或者是經過客戶端插件的方式。前者上傳組件有大小的限制,後者對於咱們系統來講實現過於複雜,開發難度稍大。所以咱們採用服務器端計算文件上傳進度,客戶端輪詢的方式。數據庫
Commons-fileupload組件自帶了文件上傳進度的監聽器,類FileUploadBase提供了它的set方法。數組
ProgressListener是一個接口,咱們須要本身實現它的update方法,參數pBytesRead表示已經上傳到服務器的字節數,pContentLength表示全部文件的總大小,pItems表示第幾個文件:
spring-mvc
文件上傳進度監聽器實現類,FileUploadProgressListener.java。
SpringMVC沒有實現監聽器,因此若是要監聽的話得本身擴展CommonsMultipartResolver類,在newFileUpload裏面加入代碼設置本身實現的監聽器:
ServletFileUploadExt是對ServletFileUpload類進行的擴展,後面會提到。這樣在文件上傳的過程當中,監聽器將獲得通知已上傳的字節數:
本身實現的Resolver類爲CustomMultipartResolver,在這個類中須要在每一次上傳請求中設定處理上傳進度的監聽器,並處理文件上傳。
protected FileUpload newFileUpload(FileItemFactory fileItemFactory) { ServletFileUpload upload = new ServletFileUpload(fileItemFactory); upload.setSizeMax(-1); if (request != null) { HttpSession session = request.getSession(); //注意:這裏的listener不能公用,即不能放到方法外面 FileUploadProgressListener progressListener = new FileUploadProgressListener(session); upload.setProgressListener(progressListener); } return upload; }
在配置文件spring-mvc-context.xml中配置使用自定義的Resolver。
<bean id="multipartResolver" class="com.sunshine.fusys.controllers.CustomMultipartResolver"> <property name="defaultEncoding" value="UTF-8" /> <property name="maxUploadSize" value="1000000000000" /> </bean>
最終在上傳時,會經過commons-fileupload的組件進行上傳時,會把上傳進度讀取到設定的session中,最後經過一個controller訪問這個設定的進度值,就能夠獲取了。獲取進度的controller爲ProgressController。客戶端採用異步的方式獲取進度信息進行展現,具體參考源碼index-userFile.jsp。
三、取消文件上傳
取消文件上傳實現方式爲上傳時保存上傳輸入流的引用,取消時關閉流,讓輸入流產生IO異常或者數組越界異常,同時捕獲這些異常,則可取消文件上傳。
最後補一個配置,spring mvc的項目訪問時默認訪問某個指定頁面或者controller的配置以下:
//轉向controller <mvc:view-controller path="/" view-name="redirect:/indexMain/index" />
或者
//轉向index.jsp <mvc:view-controller path="/" view-name="/index" />
具體可參考配置文件:spring-mvc-context.xml