springMVC是實現前臺帶進度條檔案上傳續(二)
之前寫過一遍基於springMVC是實現前臺帶進度條檔案,但是該文章僅是程式碼層面的,沒有做過多解釋,今天看到一篇文章正好對上篇文章進行了較為詳細的解釋,文章原文如下:
檔案上傳應該大部分人都接觸過,應該大部分人都接觸過,一般都是基於commons-fileupload元件來實現,SpringMVC的檔案上傳功能也是在commons-fileupload元件提供的功能上面做了一些包裝功能,使檔案上傳開發更容易方便。
看下上傳效果圖:
專案執行效果:
專案原始碼地址,釋出即可用:https://github.com/wuskyfantasy/fileupload.sys
如果下載不了也可以下截fileupload.sys-master.zip附件。
專案使用spring mvc+mybatis實現,資料庫採用mysql,具體參考README就可以釋出起來。
一、實現普通檔案上傳
我們知道,類DispatcherServlet是SpringMVC的入口,在其doDispatch方法裡面,我們可以看到它會先去檢查有沒配置multipartResolver
如果有的話會先執行它的resolveMultipart方法:
因此,我們在配置檔案中新增:
則可使用SpringMVC自帶的CommonsMultipartResolver實現多個檔案上傳的功能。
二、實現進度條
現在實現帶進度條的檔案上傳一般都是在客戶端用flash上傳元件計算,或者是通過客戶端外掛的方式。前者上傳元件有大小的限制,後者對於我們系統來說實現過於複雜,開發難度稍大。因此我們採用伺服器端計算檔案上傳進度,客戶端輪詢的方式。
Commons-fileupload元件自帶了檔案上傳進度的監聽器,類FileUploadBase提供了它的set方法。
ProgressListener是一個介面,我們需要自己實現它的update方法,引數pBytesRead表示已經上傳到伺服器的位元組數,pContentLength表示所有檔案的總大小,pItems表示第幾個檔案:
檔案上傳進度監聽器實現類,FileUploadProgressListener.java。
SpringMVC沒有實現監聽器,所以如果要監聽的話得自己擴充套件CommonsMultipartResolver類,在newFileUpload裡面加入程式碼設定自己實現的監聽器:
ServletFileUploadExt是對ServletFileUpload類進行的擴充套件,後面會提到。這樣在檔案上傳的過程中,監聽器將得到通知已上傳的位元組數:
自己實現的Resolver類為CustomMultipartResolver,在這個類中需要在每一次上傳請求中設定處理上傳進度的監聽器,並處理檔案上傳。
Java程式碼- 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;
- }
-
<span style=
"font-family:Arial;font-size:12px;">
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;
-
}</span>
在配置檔案spring-mvc-context.xml中配置使用自定義的Resolver。
Xml程式碼- <bean id="multipartResolver" class="com.sunshine.fusys.controllers.CustomMultipartResolver">
- <property name="defaultEncoding" value="UTF-8" />
- <property name="maxUploadSize" value="1000000000000" />
- </bean>
<span style="font-family:Arial;font-size:12px;"><bean id="multipartResolver" class="com.sunshine.fusys.controllers.CustomMultipartResolver"> <property name="defaultEncoding" value="UTF-8" /> <property name="maxUploadSize" value="1000000000000" /> </bean></span>
最終在上傳時,會通過commons-fileupload的元件進行上傳時,會把上傳進度讀取到設定的session中,最後通過一個controller訪問這個設定的進度值,就可以獲取了。獲取進度的controller為ProgressController。客戶端採用非同步的方式獲取進度資訊進行展示,具體參考原始碼index-userFile.jsp。
三、取消檔案上傳
取消檔案上傳實現方式為上傳時儲存上傳輸入流的引用,取消時關閉流,讓輸入流產生IO異常或者陣列越界異常,同時捕獲這些異常,則可取消檔案上傳。
最後補一個配置,spring mvc的專案訪問時預設訪問某個指定頁面或者controller的配置如下:
Xml程式碼- //轉向controller
- <mvc:view-controller path="/" view-name="redirect:/indexMain/index" />
<span style="font-family:Arial;font-size:12px;">//轉向controller <mvc:view-controller path="/" view-name="redirect:/indexMain/index" /></span>
或者
Xml程式碼
- //轉向index.jsp
- <mvc:view-controller path="/" view-name="/index" />
<span style="font-family:Arial;font-size:12px;">//轉向index.jsp <mvc:view-controller path="/" view-name="/index" /></span>
具體可參考配置檔案:spring-mvc-context.xml