最近在做一個資源共享的項目中,采用了Struts2.1.8+Spring2.5.6+hibernate3.32的框架整合方式進行開發。在文件上傳這塊,因為需要實現文件上傳時顯示進度條的功能,所以嘗試了一下。怕以后忘記,先貼出來分享下。
要在上傳文件時能顯示進度條,首先需要實時的獲知web服務端接收了多少字節,以及文件總大小,這里我們在頁面上使用AJAX技術每一秒向服務器發送一次請求來獲得需要的實時上傳信息。但是當我們使用struts2后怎么在服務端獲得實時的上傳大小呢?這里需要用到commons-fileupload中的progressListener接口,實現這個接口,然后再實現一個自己的解析器,并在解析器中添加自己實現的那個progressListener;然后再替換struts2自帶的解析器(struts2自帶的解析器類沒有添加progressListener),然后就可以了。下面看看主要的代碼(技術有限,如有不對之處,望不吝點解):
監聽器:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.apache.commons.fileupload.ProgressListener; public class ResourceProgressListener implements ProgressListener { private HttpSession session; public ResourceProgressListener(HttpServletRequest request) { session = request.getSession(); ResourceFileUploadStatus newUploadStatus = new ResourceFileUploadStatus(); session.setAttribute( "currentUploadStatus" , newUploadStatus); } public void update( long readedBytes, long totalBytes, int currentItem) { ResourceFileUploadStatus status = (ResourceFileUploadStatus) session.getAttribute( "currentUploadStatus" ); status.setReadedBytes(readedBytes); status.setTotalBytes(totalBytes); status.setCurrentItem(currentItem); } } |
上傳狀態類:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
public class ResourceFileUploadStatus { private long readedBytes = 0L; private long totalBytes = 0L; private int currentItem = 0 ; public long getReadedBytes() { return readedBytes; } public void setReadedBytes( long bytes) { readedBytes = bytes; } public long getTotalBytes() { return totalBytes; } public void setTotalBytes( long bytes) { totalBytes = bytes; } public int getCurrentItem() { return currentItem; } public void setCurrentItem( int item) { currentItem = item; } } |
實現自己的解析器類:方法比較簡單,找到struts2實現的解析器類,把代碼拷貝過來然后添加上監聽器即可。這個類代碼較多就不整個文件拷了,主要是在parse方法里添加。Parse方法代碼如下:紅色標注部分即是需要自己添加的progressListener.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
public void parse(HttpServletRequest servletRequest, String saveDir) throws IOException { System.out.println( "執行自定義MultiPartRequest" ); DiskFileItemFactory fac = new DiskFileItemFactory(); // Make sure that the data is written to file fac.setSizeThreshold( 0 ); if (saveDir != null ) { fac.setRepository( new File(saveDir)); } // Parse the request try { ServletFileUpload upload = new ServletFileUpload(fac); upload.setSizeMax(maxSize); ResourceProgressListener progressListener = new ResourceProgressListener(servletRequest); //新建一個監聽器 upload.setProgressListener(progressListener); //添加自己的監聽器 List items = upload.parseRequest(createRequestContext(servletRequest)); for (Object item1 : items) { FileItem item = (FileItem) item1; if (LOG.isDebugEnabled()) LOG.debug( "Found item " + item.getFieldName()); if (item.isFormField()) { LOG.debug( "Item is a normal form field" ); List<String> values; if (params.get(item.getFieldName()) != null ) { values = params.get(item.getFieldName()); } else { values = new ArrayList<String>(); } String charset = servletRequest.getCharacterEncoding(); if (charset != null ) { values.add(item.getString(charset)); } else { values.add(item.getString()); } params.put(item.getFieldName(), values); } else { LOG.debug( "Item is a file upload" ); // Skip file uploads that don't have a file name - meaning that no file was selected. if (item.getName() == null || item.getName().trim().length() < 1 ) { LOG.debug( "No file has been uploaded for the field: " + item.getFieldName()); continue ; } List<FileItem> values; if (files.get(item.getFieldName()) != null ) { values = files.get(item.getFieldName()); } else { values = new ArrayList<FileItem>(); } values.add(item); files.put(item.getFieldName(), values); } } } catch (FileUploadException e) { LOG.warn( "Unable to parse request" , e); errors.add(e.getMessage()); } } |
上面的類建立完成后,還需要做一項工作:在struts.xml中添加如下內容:
1
2
3
|
<bean type= "org.apache.struts2.dispatcher.multipart.MultiPartRequest" name= "requestParser" class = "com.zeige.ResourceMultiPartRequest" scope= "default" optional= "true" /> <constant name= "struts.multipart.handler" value= "requestParser" /> |
下面就可以正常使用了,建立兩個action,一個用來接收上傳文件,以及對接收的文件作相應處理,處理完成后,在return SUCCESS之前去除session中currentUploadStatus屬性,一個用來為頁面讀取實時上傳進度服務,這個類中只要將session中的currentUploadStatus對象拿出來按照相應格式返回給客戶端即可。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。