最近在做一个资源共享的项目中,采用了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对象拿出来按照相应格式返回给客户端即可。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。