您的位置:首页 > 编程语言 > Java开发

用Struts2实现文件上传时显示进度条功能

2012-03-29 11:26 711 查看
最近在做一个资源共享的项目中,采用了Struts2.1.8+Spring2.5.6+hibernate3.32的框架整合方式进行开发。在文件上传这块,因为需要实现文件上传时显示进度条的功能,所以尝试了一下。怕以后忘记,先贴出来分享下。

  要在上传文件时能显示进度条,首先需要实时的获知web服务端接收了多少字节,以及文件总大小,这里我们在页面上使用AJAX技术每一秒向服务器发送一次请求来获得需要的实时上传信息。但是当我们使用struts2后怎么在服务端获得实时的上传大小呢?这里需要用到commons-fileupload中的progressListener接口,实现这个接口,然后再实现一个自己的解析器,并在解析器中添加自己实现的那个progressListener;然后再替换struts2自带的解析器(struts2自带的解析器类没有添加progressListener),然后就可以了。下面看看主要的代码(技术有限,如有不对之处,望不吝点解):

 

监听器:

importjavax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
importorg.apache.commons.fileupload.ProgressListener;
 
public class ResourceProgressListenerimplements ProgressListener {
   private HttpSession session;
 
   public ResourceProgressListener(HttpServletRequest request){
      session = request.getSession();
      ResourceFileUploadStatus newUploadStatus =
newResourceFileUploadStatus();
      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);
    }
}

上传状态类:

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.

public void parse(HttpServletRequestservletRequest, 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);
          
           ResourceProgressListenerprogressListener =
newResourceProgressListener(servletRequest);//新建一个监听器
           upload.setProgressListener(progressListener);//添加自己的监听器
           
           List items =upload.parseRequest(createRequestContext(servletRequest));
 
           for (Object item1 : items) {
               FileItem item = (FileItem) item1
4000
;
               if (LOG.isDebugEnabled())
LOG.debug("Founditem " + 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 =
newArrayList<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 nofile 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 =
newArrayList<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中添加如下内容:

<beantype="org.apache.struts2.dispatcher.multipart.MultiPartRequest"name="requestParser"
   class="com.zeige.ResourceMultiPartRequest"scope="default" optional="true" />
<constant name="struts.multipart.handler"value="requestParser" />

 

下面就可以正常使用了,建立两个action,一个用来接收上传文件,以及对接收的文件作相应处理,处理完成后,在returnSUCCESS之前去除session中currentUploadStatus属性,一个用来为页面读取实时上传进度服务,这个类中只要将session中的currentUploadStatus对象拿出来按照相应格式返回给客户端即可。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息