Chinaunix首页 | 论坛 | 博客
  • 博客访问: 60118
  • 博文数量: 44
  • 博客积分: 2510
  • 博客等级: 少校
  • 技术积分: 470
  • 用 户 组: 普通用户
  • 注册时间: 2007-11-02 23:48
文章分类

全部博文(44)

文章存档

2009年(44)

我的朋友
最近访客

分类: 系统运维

2009-08-18 10:07:57

2.1. 服务器端代码

   2.1.1. 文件上传状态类(FileUploadStatus)

   使用FileUploadStatus这个类记录文件上传状态,并将其作为服务器端与web客户端之间通信的媒介,通过对这个类对象提供上传状态作为服务器回应发送给web客户端,web客户端使用JavaScript获得文件上传状态。源代码如下:

          /**
    * 本例程演示了通过Web上传文件过程中的进度显示。您可以对本例程进行任何修改和使用。
   *
   * 如需要转载,请注明作者。
   *
   * 作者: 刘作晨
   *
   */
package liuzuochen.sample.upload;
   import java.util.*;
   public class FileUploadStatus {
   //上传用户地址
   private String uploadAddr;
   //上传总量
   private long uploadTotalSize = 0;
   //读取上传总量
   private long readTotalSize = 0;
   //当前上传文件号
   private int currentUploadFileNum = 0;
   //成功读取上传文件数
   private int successUploadFileCount = 0;
   //状态
   private String status = "";
   //处理起始时间
   private long processStartTime = 0l;
   //处理终止时间
   private long processEndTime = 0l;
   //处理执行时间
   private long processRunningTime = 0l;
   //上传文件URL列表
   private List uploadFileUrlList = new ArrayList();
   //取消上传
   private boolean cancel = false;
   //上传base目录
   private String baseDir = "";

   public FileUploadStatus() {

   }

   public String getBaseDir() {
    return baseDir;
   }

   public void setBaseDir(String baseDir) {
    this.baseDir = baseDir;
   }

   public boolean getCancel() {
    return cancel;
   }

   public void setCancel(boolean cancel) {
    this.cancel = cancel;
   }

   public List getUploadFileUrlList() {
    return uploadFileUrlList;
   }

   public void setUploadFileUrlList(List uploadFileUrlList)
{    this.uploadFileUrlList = uploadFileUrlList;
   }

   public long getProcessRunningTime() {
    return processRunningTime;
   }

   public void setProcessRunningTime(long
processRunningTime) {
    this.processRunningTime = processRunningTime;
   }

   public long getProcessEndTime() {
    return processEndTime;
   }

   public void setProcessEndTime(long processEndTime) {
    this.processEndTime = processEndTime;
   }

   public long getProcessStartTime() {
    return processStartTime;
   }

   public void setProcessStartTime(long processStartTime) {
    this.processStartTime = processStartTime;
   }

   public long getReadTotalSize() {
    return readTotalSize;
   }

   public void setReadTotalSize(long readTotalSize) {
    this.readTotalSize = readTotalSize;
   }

   public int getSuccessUploadFileCount() {
    return successUploadFileCount;
   }

   public void setSuccessUploadFileCount(int
successUploadFileCount) {
    this.successUploadFileCount =
successUploadFileCount;
   }

   public int getCurrentUploadFileNum() {
    return currentUploadFileNum;
   }

   public void setCurrentUploadFileNum(int
currentUploadFileNum) {
    this.currentUploadFileNum = currentUploadFileNum;
   }

   public String getStatus() {
    return status;
   }

   public void setStatus(String status) {
    this.status = status;
   }

   public long getUploadTotalSize() {
    return uploadTotalSize;
   }

   public String getUploadAddr() {
    return uploadAddr;
   }

   public void setUploadTotalSize(long uploadTotalSize) {
    this.uploadTotalSize = uploadTotalSize;
   }

   public void setUploadAddr(String uploadAddr) {
    this.uploadAddr = uploadAddr;
   }

   public String toJSon() {
    StringBuffer strJSon = new StringBuffer();
    strJSon.append("
{UploadTotalSize:").append(getUploadTotalSize()).append(
      ",")
      .append
("ReadTotalSize:").append(getReadTotalSize()).append
(",")
      .append
("CurrentUploadFileNum:").append(getCurrentUploadFileNum()).
      append(",")
      .append
("SuccessUploadFileCount:").append(
      
getSuccessUploadFileCount()).append(",")      .append
("Status:'").append(getStatus()).append("',")      .append
("ProcessStartTime:").append(getProcessStartTime()).      append(",")
      .append("ProcessEndTime:").append(getProcessEndTime()).append(        ",")
      .append("ProcessRunningTime:").append(getProcessRunningTime()).
      append(",")      .append("Cancel:").append(getCancel()).append("}");
    return strJSon.toString();

   }
    }
  

   2.1.2. 文件上传状态侦听类(FileUploadListener)

   使用Common-FileUpload 1.2版本(20070103)。此版本提供了能够监视文件上传情况的 ProcessListener接口,
使开发者通过FileUploadBase类对象的setProcessListener方法植入自己的Listener。
FileUploadListener类实现了ProcessListener,在整个文件上传过程中,它对上传进度进行监控,
并且根据上传 情况实时的更新上传状态Bean。源代码如下:

   /**
   * 本例程演示了通过Web上传文件过程中的进度显示。您可以对本例程进行任何修改和使用。
   *
   * 如需要转载,请注明作者。
   *
   * 作者: 刘作晨
   *
   */
package liuzuochen.sample.upload;

import org.apache.commons.fileupload.ProgressListener;
import javax.servlet.http.HttpServletRequest;

public class FileUploadListener implements ProgressListener{
   private HttpServletRequest request=null;


public FileUploadListener(HttpServletRequest request){
   this.request=request;
}

/**
   * 更新状态
   */
public void update(long pBytesRead, long pContentLength, int pItems){
   FileUploadStatus statusBean= BackGroundService.getStatusBean(request);
   statusBean.setUploadTotalSize(pContentLength);
   //读取完成
   if (pContentLength == -1) {
      statusBean.setStatus("完成对" + pItems +"个文件的读取:读取了 " + pBytesRead + " bytes.");
      statusBean.setReadTotalSize(pBytesRead);
      statusBean.setSuccessUploadFileCount(pItems);
      statusBean.setProcessEndTime(System.currentTimeMillis());
      statusBean.setProcessRunningTime(statusBean.getProcessEndTime());
   //读取中
   } else {
      statusBean.setStatus("当前正在处理第" + pItems +"个文件:已经读取了 " + pBytesRead + " / " + pContentLength+ " bytes.");
      statusBean.setReadTotalSize(pBytesRead);
      statusBean.setCurrentUploadFileNum(pItems);
      statusBean.setProcessRunningTime(System.currentTimeMillis());
   }
    BackGroundService.saveStatusBean(request,statusBean);
}
}  

   2.1.3. 后台服务类(BackGroundService)

   BackGroundService这个Servlet类负责接收Form Post数据、回应状态轮询请求、处理取消文件上传的请求。
尽管可以把这些功能相互分离开来,但为了简单明了,还是将它们放到Servlet中,只是由不同的方法进行分割。
源代码如下:

   
/**
   * 本例程演示了通过Web上传文件过程中的进度显示。您可以对本例程进行任何修改和使用。
   *
   * 如需要转载,请注明作者。
   *
   * 作者: 刘作晨
   *
   */
package liuzuochen.sample.upload;

import java.io.File;
import java.io.IOException;
import java.util.List;


import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.*;


public class BackGroundService extends javax.servlet.http.HttpServlet implements    javax.servlet.Servlet {

   public static final String UPLOAD_DIR = "/upload";
   public static final String DEFAULT_UPLOAD_FAILURE_URL = "./result.jsp";

   public BackGroundService() {
    super();
   }


   protected void doGet(HttpServletRequest request,         HttpServletResponse response) throws ServletException,     IOException {
    doPost(request, response);
   }
   /**
    * 从文件路径中取出文件名
    */
   private String takeOutFileName(String filePath) {
    int pos = filePath.lastIndexOf(File.separator);
    if (pos > 0) {
     return filePath.substring(pos + 1);
    } else {
     return filePath;
    }
   }

   /**
    * 从request中取出FileUploadStatus Bean
    */
   public static FileUploadStatus getStatusBean(
     HttpServletRequest request) {
    BeanControler beanCtrl = BeanControler.getInstance();
    return beanCtrl.getUploadStatus(request.getRemoteAddr());
   }
   /**
    * 把FileUploadStatus Bean保存到类控制器BeanControler
    */
   public static void saveStatusBean(     HttpServletRequest request,     FileUploadStatus statusBean) {
    statusBean.setUploadAddr(request.getRemoteAddr());
    BeanControler beanCtrl = BeanControler.getInstance();
    beanCtrl.setUploadStatus(statusBean);
   }

   /**
    * 删除已经上传的文件
    */
   private void deleteUploadedFile(HttpServletRequest request) {
    FileUploadStatus satusBean = getStatusBean(request);
    for (int i = 0; i < satusBean.getUploadFileUrlList().size(); i++) {
     File uploadedFile = new File(request.getRealPath(UPLOAD_DIR) +             File.separator +             satusBean.getUploadFileUrlList().             get(i));
     uploadedFile.delete();
    }
    satusBean.getUploadFileUrlList().clear();
    satusBean.setStatus("删除已上传的文件");
    saveStatusBean(request, satusBean);
   }

   /**
    * 上传过程中出错处理
    */
   private void uploadExceptionHandle(     HttpServletRequest request,     String errMsg) throws ServletException, IOException {
    //首先删除已经上传的文件
    deleteUploadedFile(request);
    FileUploadStatus satusBean = getStatusBean(request);
    satusBean.setStatus(errMsg);
    saveStatusBean(request, satusBean);
   }

   /**
    * 初始化文件上传状态Bean
    */
   private FileUploadStatus initStatusBean(HttpServletRequest
     request) {
    FileUploadStatus satusBean = new FileUploadStatus();
    satusBean.setStatus("正在准备处理");
    satusBean.setUploadTotalSize(request.getContentLength());
    satusBean.setProcessStartTime(System.currentTimeMillis());
    satusBean.setBaseDir(request.getContextPath() + UPLOAD_DIR);
    return satusBean;
   }

   /**
    * 处理文件上传
    */
   private void processFileUpload(HttpServletRequest request,
        
     HttpServletResponse response) throws     ServletException, IOException {
    DiskFileItemFactory factory = new DiskFileItemFactory();
    //设置内存缓冲区,超过后写入临时文件
    factory.setSizeThreshold(10240000);
    //设置临时文件存储位置
    factory.setRepository(new File(request.getRealPath("/upload/temp")));
    ServletFileUpload upload = new ServletFileUpload(factory);
    //设置单个文件的最大上传值
    upload.setFileSizeMax(102400000);
    //设置整个request的最大值
    upload.setSizeMax(102400000);
    upload.setProgressListener(new FileUploadListener(request));
    //保存初始化后的FileUploadStatus Bean
    saveStatusBean(request, initStatusBean(request));

    String forwardURL = "";
    try {
     List items = upload.parseRequest(request);
     //获得返回url
     for (int i = 0; i < items.size(); i++) {
      FileItem item = (FileItem) items.get(i);
      if (item.isFormField()) {
       forwardURL = item.getString();
       break;
      }
     }
     //处理文件上传
     for (int i = 0; i < items.size(); i++) {
      FileItem item = (FileItem) items.get(i);

      //取消上传
      if (getStatusBean(request).getCancel()) {
       deleteUploadedFile(request);
       break;
      }
      //保存文件
      else if (!item.isFormField() && item.getName().length() > 0) {
       String fileName = takeOutFileName(item.getName());
       File uploadedFile = new File(request.getRealPath(UPLOAD_DIR) +
               File.separator + fileName);       item.write(uploadedFile);       //更新上传文件列表       FileUploadStatus
satusBean =         getStatusBean(request);     
satusBean.getUploadFileUrlList().add(fileName);
       saveStatusBean(request, satusBean);
       Thread.sleep(500);
      }
     }

    } catch (FileUploadException e) {
     uploadExceptionHandle(request, "上传文件时发生错误:" + e.getMessage());
    } catch (Exception e) {
     uploadExceptionHandle(request, "保存上传文件时发生错误:" + e.getMessage());
    }
    if (forwardURL.length() == 0) {
     forwardURL = DEFAULT_UPLOAD_FAILURE_URL;
    }
    request.getRequestDispatcher(forwardURL).forward(request, response);
   }

   /**
    * 回应上传状态查询
    */
   private void responseStatusQuery(HttpServletRequest request,
         
      HttpServletResponse response) throws     IOException {
    response.setContentType("text/xml");
    response.setCharacterEncoding("UTF-8");
    response.setHeader("Cache-Control", "no-cache");
    FileUploadStatus satusBean = getStatusBean(request);
    response.getWriter().write(satusBean.toJSon());
   }

   /**
    * 处理取消文件上传
    */
   private void processCancelFileUpload(HttpServletRequest request,
         
    HttpServletResponse response) throws     IOException {
    FileUploadStatus satusBean = getStatusBean(request);
    satusBean.setCancel(true);
    saveStatusBean(request, satusBean);
    responseStatusQuery(request, response);
   }

   protected void doPost(HttpServletRequest request,
          HttpServletResponse response) throws ServletException,     IOException {
    boolean isMultipart = ServletFileUpload.isMultipartContent(request);
    if (isMultipart) {
     processFileUpload(request, response);
    } else {
     request.setCharacterEncoding("UTF-8");

     if (request.getParameter("uploadStatus") != null) {
      responseStatusQuery(request, response);
     }
     if (request.getParameter("cancelUpload") != null) {
      processCancelFileUpload(request, response);
     }

    }
   }
}
  

   2.1.4. 文件上传状态控制类(BeanControler)

   这是一个单例类,它的功能是为客户端保存文件上传状态,这里我没有使用Session来存储 文件上传状态,
因为对于AJAX这种异步调用,服务器会开启不同的Session,所以无法通过Session保存文件上传状态。
我并不认为这种方法最好,如果有更好的方法,欢迎大家一起讨论。 源代码如下:

  
/**
   * 本例程演示了通过Web上传文件过程中的进度显示。您可以对本例程进行任何修改和使用。
   *
   * 如需要转载,请注明作者。
   *
   * 作者: 刘作晨
   *
   */   
   package liuzuochen.sample.upload;
  
   import java.util.Vector;
  
   public class BeanControler {
    private static BeanControler beanControler = new BeanControler();
    private Vector vector = new Vector();
    private BeanControler() {
    }
  
    public static BeanControler getInstance() {
     return beanControler;
    }
  
    /**
     * 取得相应FileUploadStatus类对象的存储位置
     */
    private int indexOf(String strID) {
     int nReturn = -1;
     for (int i = 0; i < vector.size(); i++) {
      FileUploadStatus status = (FileUploadStatus) vector.elementAt(i);
      if (status.getUploadAddr().equals(strID)) {
       nReturn = i;
       break;
      }
     }
     return nReturn;
    }
    /**
     * 取得相应FileUploadStatus类对象
     */
    public FileUploadStatus getUploadStatus(String strID) {
     return (FileUploadStatus) vector.elementAt(indexOf(strID));
    }
    /**
     * 存储FileUploadStatus类对象
     */
    public void setUploadStatus(FileUploadStatus status) {
     int nIndex = indexOf(status.getUploadAddr());
     if ( -1 == nIndex) {
      vector.add(status);
     } else {
      vector.insertElementAt(status, nIndex);
      vector.removeElementAt(nIndex + 1);
     }
    }
    /**
     * 删除FileUploadStatus类对象
     */
    public void removeUploadStatus(String strID){
     int nIndex = indexOf(strID);
     if(-1!=nIndex)
      vector.removeElementAt(nIndex);
    }
   }
阅读(321) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~