当前位置: 代码迷 >> Web前端 >> AJAX+JSP实现基于WEB的文件下传的进度控制(2)
  详细解决方案

AJAX+JSP实现基于WEB的文件下传的进度控制(2)

热度:117   发布时间:2012-11-22 00:16:41.0
AJAX+JSP实现基于WEB的文件上传的进度控制(2)

2.1.3. 后台服务类(BackGroundService)

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

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


/**
 * Title: 后台服务
 * * Description: 为客户端提供上传及文件传输状态查询服务
 *
 */
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.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上传文件过程中的进度显示。您可以对本例程进行任何修改和使用。
 * 如果需要转载本例程,请您注明作者。
 *
 * 作者: 刘作晨
 * EMail:liuzuochen@gmail.com
 */

package liuzuochen.sample.upload;
/**
 * Title: 类控制器
 *
 * Description: 主要作用是对FileUploadStatus进行管理,为客户端提供相应的
 * FileUploadStatus类对象。这是一个单例类。
 *
 */
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);
???? }
}

2.2. 客户端代码

   客户端我们采用Prototype框架。请下载。

?? 2.2.1. AjaxWrapper.js

   AjaxWrapper.js对Prototype进行了封装。请下载分析

?? 2.2.2. fileUpload.html

   fileUpload.html是文件上传界面。 请下载。

?? 2.2.3. result.jsp

   result.jsp是文件上传结果显示界面。 请下载

?? 2.2.4. fileUpload.css

   fileUpload.css是样式文件。 源代码如下:

body {
color:#000;
background-color:white;
font:15px Georgia, "Lucida Grande", Arial, sans-serif;
letter-spacing:0.01em;
margin:15px;
}
#controlPanel,#resultPanel{
width:700px;
margin:20px auto;
padding:25px;
border:3px solid gray;
-moz-border-radius:10px;
background:#f8f8f8;
}
#errorArea{
width:400px;
margin:20px auto;
padding:25px;
border:3px solid gray;
-moz-border-radius:10px;
background:red;
}
#normalMessageArea{
width:400px;
margin:20px auto;
padding:25px;
border:3px solid gray;
-moz-border-radius:10px;
background:yellow;
}
#progressBar { padding-top: 5px; }
#totalProgressBarBox {
width: 350px;
height: 20px;
border: 1px inset;
background: #eee;
}
#totalProgressBarBoxContent {
width: 0;
height: 20px;
border-right: 1px solid #444;
background: #9ACB34;
}

2.3. 配置文件

   web.xml中完成Servlet的配置。

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>AjaxPractice</display-name>
<servlet>
<description></description>
<display-name>BackGroundService</display-name>
<servlet-name>BackGroundService</servlet-name>
<servlet-class>liuzuochen.sample.upload.BackGroundService</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>BackGroundService</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>

3. 结语

   整个程序到这里就介绍完了,希望它多少能为您的工作或学习带来点儿帮助。

1 楼 mogui258 2010-08-22  
没看见源码啊?
怎么下载?
  相关解决方案