⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ajax实现基于web的文件上传的进度控制 - liuzuochen的专栏 - csdnblog.htm

📁 主要是我最近两月在公司通过百度学习的内容,有AJAX,DWR,JAVA实现文件的上传和下载.主要目的在与告诉大家一个成功程序员(JAVA)是如何学习的,需要学习什么内容.以及学习的态度.
💻 HTM
📖 第 1 页 / 共 5 页
字号:
      target=_blank>BLOG首页</A>&nbsp;|&nbsp; <A id=Header1_MyLinks1_PersonalHome 
      title="访问 liuzuochen的专栏" href="http://blog.csdn.net/liuzuochen/" 
      target=_blank>我的首页</A>&nbsp;|&nbsp; <A id=Header1_MyLinks1_PersonalResume 
      href="http://job.csdn.net/resumes/liuzuochen.aspx">个人档案</A>&nbsp;|&nbsp; 
      <A id=Header1_MyLinks1_ContactLink accessKey=9 
      href="http://blog.csdn.net/liuzuochen/contact.aspx">联系作者</A>&nbsp;|&nbsp; 
      <A id=Header1_MyLinks1_Syndication 
      href="http://blog.csdn.net/liuzuochen/Rss.aspx">聚合</A> <A class=XMLLink 
      id=Header1_MyLinks1_XMLLink 
      href="http://blog.csdn.net/liuzuochen/Rss.aspx"><IMG 
      src="AJAX实现基于WEB的文件上传的进度控制 - liuzuochen的专栏 - CSDNBlog.files/xml.gif" 
      border=0></A>&nbsp;|&nbsp; <A id=Header1_MyLinks1_HyperLink1 
      href="http://search.csdn.net/search_blog.asp" 
      target=_blank>搜索</A>&nbsp;|&nbsp; <A id=Header1_MyLinks1_Admin 
      href="http://writeblog.csdn.net/">登录</A> <IMG id=Header1_BlueTab 
      src="AJAX实现基于WEB的文件上传的进度控制 - liuzuochen的专栏 - CSDNBlog.files/BlueTabRight.jpg" 
      align=absMiddle border=0> </TD>
    <TD class=HeaderBarTabBack noWrap width="100%">
      <DIV class=BlogStatsBar>
      <TABLE class=BlogStatsBar>
        <TBODY>
        <TR>
          <TD width="100%"></TD>
          <TD class=BlogStatsBar noWrap>&nbsp; 1篇原创: 0篇翻译: 0篇转载: 1897次点击: 
            27个评论: 0个Trackbacks 
</TD></TR></TBODY></TABLE></DIV></TD></TR></TBODY></TABLE></DIV></DIV>
<DIV id=leftmenu>
<H3 class=listtitle>文章</H3>
<UL class=list></UL>
<H3 class=listtitle>收藏</H3>
<UL class=list></UL>
<H3 class=listtitle>相册</H3><!--category title-->
<UL class=list>
  <LI class=listitem><A 
  href="http://blog.csdn.net/liuzuochen/Gallery/280560.aspx">运行界面</A></LI></UL>
<H3 class=listtitle>存档</H3>
<UL class=list>
  <LI><A 
  href="http://blog.csdn.net/liuzuochen/archive/2007/02.aspx">2007年02月(1)</A></LI></UL><SPAN 
id=Anthem_RecentComments_ltlComments__><SPAN id=RecentComments_ltlComments>
<H3 class=listtitle>最近评论</H3>
<UL class=list>
  <LI class=listitem>liq330:<A title=点击查看《回复:AJAX实现基于WEB的文件上传的进度控制》 
  href="http://blog.csdn.net/liuzuochen/archive/2007/02/28/1516522.aspx#543360">给我,谢谢<BR>lizy-123@163.com</A>
  <LI class=listitem>liq330:<A title=点击查看《回复:AJAX实现基于WEB的文件上传的进度控制》 
  href="http://blog.csdn.net/liuzuochen/archive/2007/02/28/1516522.aspx#543353">jsp的<BR><BR>liq330@gmail.com</A>
  <LI class=listitem>wenzhoufeng:<A title=点击查看《回复:AJAX实现基于WEB的文件上传的进度控制》 
  href="http://blog.csdn.net/liuzuochen/archive/2007/02/28/1516522.aspx#543325"><A 
  href="http://www.66soft.com/">&lt;img 
  src=http://www.66soft.com/Linkpic/2007261625564033.gif alt=66软站 
  border=0&gt;</A><BR>你好,你能给我的站点做一个友情链接吗.<BR>我们的友情链接申请添加是:http://www.66soft.com/service/Re……</A>
  <LI class=listitem>wenzhoufeng:<A title=点击查看《回复:AJAX实现基于WEB的文件上传的进度控制》 
  href="http://blog.csdn.net/liuzuochen/archive/2007/02/28/1516522.aspx#543324"><A 
  href="http://www.66soft.com/">&lt;img 
  src=http://www.66soft.com/Linkpic/2007261625564033.gif alt=66软站 
  border=0&gt;</A><BR>你好,你能给我的站点做一个友情链接吗.<BR>我们的友情链接申请添加是:http://www.66soft.com/service/Re……</A>
  <LI class=listitem>wubaojie:<A title=点击查看《回复:AJAX实现基于WEB的文件上传的进度控制》 
  href="http://blog.csdn.net/liuzuochen/archive/2007/02/28/1516522.aspx#543300">wubj757@163.com<BR>谢谢</A></LI></UL></SPAN></SPAN><BR><BR></DIV>
<DIV id=main>
<DIV class=Tag>
<SCRIPT language=javascript 
src="AJAX实现基于WEB的文件上传的进度控制 - liuzuochen的专栏 - CSDNBlog.files/urltag.aspx"></SCRIPT>

<DIV style="CLEAR: both"></DIV></DIV>
<SCRIPT>function StorePage(){d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(keyit=window.open('http://www.365key.com/storeit.aspx?t='+escape(d.title)+'&u='+escape(d.location.href)+'&c='+escape(t),'keyit','scrollbars=no,width=475,height=575,left=75,top=20,status=no,resizable=yes'));keyit.focus();}</SCRIPT>

<DIV class=post>
<DIV class=postTitle><A 
href="http://blog.csdn.net/liuzuochen/archive/2007/02/28/1516522.aspx"><IMG 
height=13 
src="AJAX实现基于WEB的文件上传的进度控制 - liuzuochen的专栏 - CSDNBlog.files/authorship.gif" 
width=15 border=0>&nbsp;AJAX实现基于WEB的文件上传的进度控制</A> </DIV>
<DIV class=postText>
<STYLE type=text/css>BODY {
	MARGIN: 15px; FONT: 13px Georgia, "Lucida Grande", Arial, sans-serif; COLOR: #000; LETTER-SPACING: 0.01em; BACKGROUND-COLOR: white
}
PRE.programlisting {
	PADDING-RIGHT: 6px; PADDING-LEFT: 6px; FONT-SIZE: small; PADDING-BOTTOM: 6px; PADDING-TOP: 6px; FONT-FAMILY: Courier New, monospace; BACKGROUND-COLOR: #f4f4f4
}
</STYLE>
<A id=d0 name=d0></A>
<DIV class=toc>
<DL>
  <DT>1. <A 
  href="http://blog.csdn.net/liuzuochen/archive/2007/02/28/1516522.aspx#d1">引言</A> 

  <DT>2. <A 
  href="http://blog.csdn.net/liuzuochen/archive/2007/02/28/1516522.aspx#d2">实现代码</A> 

  <DD>
  <DL>
    <DT>2.1. <A 
    href="http://blog.csdn.net/liuzuochen/archive/2007/02/28/1516522.aspx#d201">服务器端代码</A> 

    <DD>
    <DL>
      <DT>2.1.1. <A 
      href="http://blog.csdn.net/liuzuochen/archive/2007/02/28/1516522.aspx#d20101">文件上传状态类(FileUploadStatus)</A> 

      <DT>2.1.2. <A 
      href="http://blog.csdn.net/liuzuochen/archive/2007/02/28/1516522.aspx#d20102">文件上传状态侦听类(FileUploadListener)</A> 

      <DT>2.1.3. <A 
      href="http://blog.csdn.net/liuzuochen/archive/2007/02/28/1516522.aspx#d20103">后台服务类(BackGroundService)</A> 

      <DT>2.1.4. <A 
      href="http://blog.csdn.net/liuzuochen/archive/2007/02/28/1516522.aspx#d20104">文件上传状态控制类(BeanControler)</A> 
      </DT></DL>
    <DT>2.2. <A 
    href="http://blog.csdn.net/liuzuochen/archive/2007/02/28/1516522.aspx#d202">客户端代码</A> 

    <DD>
    <DL>
      <DT>2.2.1. <A 
      href="http://blog.csdn.net/liuzuochen/archive/2007/02/28/1516522.aspx#d20201">AjaxWrapper.js</A> 

      <DT>2.2.2. <A 
      href="http://blog.csdn.net/liuzuochen/archive/2007/02/28/1516522.aspx#d20202">fileUpload.html</A> 

      <DT>2.2.3. <A 
      href="http://blog.csdn.net/liuzuochen/archive/2007/02/28/1516522.aspx#d20203">result.jsp</A> 

      <DT>2.2.4. <A 
      href="http://blog.csdn.net/liuzuochen/archive/2007/02/28/1516522.aspx#d20204">fileUpload.css</A> 
      </DT></DL>
    <DT>2.3. <A 
    href="http://blog.csdn.net/liuzuochen/archive/2007/02/28/1516522.aspx#d203">配置文件</A> 
    </DT></DL>
  <DT>3. <A 
  href="http://blog.csdn.net/liuzuochen/archive/2007/02/28/1516522.aspx#d3">结语</A> 
  </DT></DL></DIV>
<DIV>
<DIV>
<H2 class=title><A id=d1 name=d1></A>&nbsp;1.&nbsp;引言</H2></DIV></DIV>
<DIV><A 
href="http://blog.csdn.net/liuzuochen/archive/2007/02/28/1516522.aspx#d0">返回</A></DIV>
<DIV></DIV>
<P>   基于浏览器的文件上传,特别是对于通过&lt;input 
type="file"&gt;标签来实现上传的情况,<BR>存在着严重的性能问题,因为用户提交了文件之后,在浏览器把文件上传到服务器的过程中,界面看上去<BR>似乎是静止的,如果是小文件还好些,如果不幸需要上传的是几兆、几十兆甚至上百兆的文件,我相信那是<BR>一种非常痛苦的体验,我们中间的很多人应该都有过此种不堪的经历。(一笑)</P>
<P>  现在我就针对这个问题给出一个解决方案,我们将实现一个具有监控能力的WEB上传的程序——它不仅<BR>把文件上传到服务器,而且"实时地"监视文件上传的实际过程。</P>
<P>解决方案的基本思路是这样的:<BR><BR></P>
<UL>
  <LI>  在Form提交上传文件同时,使用AJAX周期性地从Servlet轮询上传状态信息 
  <LI>  然后,根据此信息更新进度条和相关文字,及时反映文件传输状态 
  <LI>  如果用户取消上传操作,则进行相应的现场清理工作:删除已经上传的文件,在Form提交页面中显示相关信息 
  <LI>  如果上传完毕,显示已经上传的文件内容(或链接) </LI></UL>
<P>在介绍源代码之前,我们先来看看程序运行界面:<BR><IMG alt="" 
src="AJAX实现基于WEB的文件上传的进度控制 - liuzuochen的专栏 - CSDNBlog.files/o_pic.jpg"> </P>
<DIV>
<DIV>
<H2 class=title><A id=d2 name=d2></A>&nbsp;2.&nbsp;实现代码</H2></DIV></DIV>
<DIV><A 
href="http://blog.csdn.net/liuzuochen/archive/2007/02/28/1516522.aspx#d0">返回</A></DIV>
<DIV></DIV>
<P>   实现代码想当然的有服务器端代码和客户端代码(呵呵),我们先从服务器端开始。</P>
<DIV>
<DIV>
<H2 class=title style="CLEAR: both"><A id=d201 
name=d201></A>&nbsp;2.1.&nbsp;服务器端代码</H2></DIV></DIV>
<DIV>
<DIV>
<H3 class=title><A 
name=d20101></A>&nbsp;&nbsp;2.1.1.&nbsp;文件上传状态类(FileUploadStatus)</H3></DIV>
<DIV><A 
href="http://blog.csdn.net/liuzuochen/archive/2007/02/28/1516522.aspx#d0">返回</A></DIV></DIV>
<P>   
使用FileUploadStatus这个类记录文件上传状态,并将其作为服务器端与web客户端之间通信的媒介,通过对这个类对象提供上传状态作为服务器回应发送给web客户端,web客户端使用JavaScript获得文件上传状态。源代码如下:</P><PRE class=programlisting>	        /**<BR> 	 * 本例程演示了通过Web上传文件过程中的进度显示。您可以对本例程进行任何修改和使用。<BR>	 *<BR>	 * 如需要转载,请注明作者。<BR>	 *<BR>	 * 作者: 刘作晨<BR>	 * <BR>	 */<BR>	package liuzuochen.sample.upload;<BR>		import java.util.*;<BR>		public class FileUploadStatus {<BR>		//上传用户地址<BR>		private String uploadAddr;<BR>		//上传总量<BR>		private long uploadTotalSize = 0;<BR>		//读取上传总量<BR>		private long readTotalSize = 0;<BR>		//当前上传文件号<BR>		private int currentUploadFileNum = 0;<BR>		//成功读取上传文件数<BR>		private int successUploadFileCount = 0;<BR>		//状态<BR>		private String status = "";<BR>		//处理起始时间<BR>		private long processStartTime = 0l;<BR>		//处理终止时间<BR>		private long processEndTime = 0l;<BR>		//处理执行时间<BR>		private long processRunningTime = 0l;<BR>		//上传文件URL列表<BR>		private List uploadFileUrlList = new ArrayList();<BR>		//取消上传<BR>		private boolean cancel = false;<BR>		//上传base目录<BR>		private String baseDir = "";<BR>	<BR>		public FileUploadStatus() {<BR>	<BR>		}<BR>	<BR>		public String getBaseDir() {<BR>			return baseDir;<BR>		}<BR>	<BR>		public void setBaseDir(String baseDir) {<BR>			this.baseDir = baseDir;<BR>		}<BR>	<BR>		public boolean getCancel() {<BR>			return cancel;<BR>		}<BR>	<BR>		public void setCancel(boolean cancel) {<BR>			this.cancel = cancel;<BR>		}<BR>	<BR>		public List getUploadFileUrlList() {<BR>			return uploadFileUrlList;<BR>		}<BR>	<BR>		public void setUploadFileUrlList(List uploadFileUrlList) <BR>{			this.uploadFileUrlList = uploadFileUrlList;<BR>		}<BR>	<BR>		public long getProcessRunningTime() {<BR>			return processRunningTime;<BR>		}<BR>	<BR>		public void setProcessRunningTime(long <BR>processRunningTime) {<BR>			this.processRunningTime = processRunningTime;<BR>		}<BR>	<BR>		public long getProcessEndTime() {<BR>			return processEndTime;<BR>		}<BR>	<BR>		public void setProcessEndTime(long processEndTime) {<BR>			this.processEndTime = processEndTime;<BR>		}<BR>	<BR>		public long getProcessStartTime() {<BR>			return processStartTime;<BR>		}<BR>	<BR>		public void setProcessStartTime(long processStartTime) {<BR>			this.processStartTime = processStartTime;<BR>		}<BR>	<BR>		public long getReadTotalSize() {<BR>			return readTotalSize;<BR>		}<BR>	<BR>		public void setReadTotalSize(long readTotalSize) {<BR>			this.readTotalSize = readTotalSize;<BR>		}<BR>	<BR>		public int getSuccessUploadFileCount() {<BR>			return successUploadFileCount;<BR>		}<BR>	<BR>		public void setSuccessUploadFileCount(int <BR>successUploadFileCount) {<BR>			this.successUploadFileCount = <BR>successUploadFileCount;<BR>		}<BR>	<BR>		public int getCurrentUploadFileNum() {<BR>			return currentUploadFileNum;<BR>		}<BR>	<BR>		public void setCurrentUploadFileNum(int <BR>currentUploadFileNum) {<BR>			this.currentUploadFileNum = currentUploadFileNum;<BR>		}<BR>	<BR>		public String getStatus() {<BR>			return status;<BR>		}<BR>	<BR>		public void setStatus(String status) {<BR>			this.status = status;<BR>		}<BR>	<BR>		public long getUploadTotalSize() {<BR>			return uploadTotalSize;<BR>		}<BR>	<BR>		public String getUploadAddr() {<BR>			return uploadAddr;<BR>		}<BR>	<BR>		public void setUploadTotalSize(long uploadTotalSize) {<BR>			this.uploadTotalSize = uploadTotalSize;<BR>		}<BR>	<BR>		public void setUploadAddr(String uploadAddr) {<BR>			this.uploadAddr = uploadAddr;<BR>		}<BR>	<BR>		public String toJSon() {<BR>			StringBuffer strJSon = new StringBuffer();<BR>			strJSon.append("<BR>{UploadTotalSize:").append(getUploadTotalSize()).append(<BR>					",")<BR>					.append<BR>("ReadTotalSize:").append(getReadTotalSize()).append<BR>(",")<BR>					.append<BR>("CurrentUploadFileNum:").append(getCurrentUploadFileNum()).<BR>					append(",")<BR>					.append<BR>("SuccessUploadFileCount:").append(<BR>						<BR>	getSuccessUploadFileCount()).append(",")					.append<BR>("Status:'").append(getStatus()).append("',")					.append<BR>("ProcessStartTime:").append(getProcessStartTime()).					append(",")<BR>					.append("ProcessEndTime:").append(getProcessEndTime()).append(							",")<BR>					.append("ProcessRunningTime:").append(getProcessRunningTime()).<BR>					append(",")					.append("Cancel:").append(getCancel()).append("}");<BR>			return strJSon.toString();<BR>	<BR>		}<BR>			}<BR>		</PRE>
<DIV>
<DIV>
<H3 class=title><A 
name=d20102></A>&nbsp;&nbsp;2.1.2.&nbsp;文件上传状态侦听类(FileUploadListener)</H3></DIV>
<DIV><A 
href="http://blog.csdn.net/liuzuochen/archive/2007/02/28/1516522.aspx#d0">返回</A></DIV></DIV>
<P>   使用Common-FileUpload 1.2版本(20070103)。此版本提供了能够监视文件上传情况的 
ProcessListener接口,<BR>使开发者通过FileUploadBase类对象的setProcessListener方法植入自己的Listener。<BR>FileUploadListener类实现了ProcessListener,在整个文件上传过程中,它对上传进度进行监控,<BR>并且根据上传 
情况实时的更新上传状态Bean。源代码如下:</P><PRE class=programlisting> 	/**<BR>	 * 本例程演示了通过Web上传文件过程中的进度显示。您可以对本例程进行任何修改和使用。<BR>	 *<BR>	 * 如需要转载,请注明作者。<BR>	 *<BR>	 * 作者: 刘作晨<BR>	 * <BR>	 */<BR>	package liuzuochen.sample.upload;<BR>	<BR>	import org.apache.commons.fileupload.ProgressListener;<BR>	import javax.servlet.http.HttpServletRequest;<BR>	<BR>	public class FileUploadListener implements ProgressListener{<BR>		private HttpServletRequest request=null;<BR>	<BR>	<BR>	public FileUploadListener(HttpServletRequest request){	<BR>		this.request=request;	<BR>	}	<BR>	<BR>	/**	<BR>	 * 更新状态	<BR>	 */	<BR>	public void update(long pBytesRead, long pContentLength, int pItems){	<BR>		FileUploadStatus statusBean= BackGroundService.getStatusBean(request);	<BR>		statusBean.setUploadTotalSize(pContentLength);	<BR>		//读取完成	<BR>		if (pContentLength == -1) {	<BR>		   statusBean.setStatus("完成对" + pItems +"个文件的读取:读取了 " + pBytesRead + " bytes.");	<BR>		   statusBean.setReadTotalSize(pBytesRead);	<BR>		   statusBean.setSuccessUploadFileCount(pItems);	<BR>		   statusBean.setProcessEndTime(System.currentTimeMillis());	<BR>		   statusBean.setProcessRunningTime(statusBean.getProcessEndTime());	<BR>		//读取中	<BR>		} else {	<BR>		   statusBean.setStatus("当前正在处理第" + pItems +"个文件:已经读取了 " + pBytesRead + " / " + pContentLength+ " bytes.");	<BR>		   statusBean.setReadTotalSize(pBytesRead);	<BR>		   statusBean.setCurrentUploadFileNum(pItems);	<BR>		   statusBean.setProcessRunningTime(System.currentTimeMillis());	<BR>		}	<BR>			BackGroundService.saveStatusBean(request,statusBean);	<BR>	}<BR>	}		</PRE>
<DIV>
<DIV>
<H3 class=title><A 
name=d20103></A>&nbsp;&nbsp;2.1.3.&nbsp;后台服务类(BackGroundService)</H3></DIV>
<DIV><A 
href="http://blog.csdn.net/liuzuochen/archive/2007/02/28/1516522.aspx#d0">返回</A></DIV></DIV>
<P>   BackGroundService这个Servlet类负责接收Form Post数据、回应状态轮询请求、处理取消文件上传的请求。 
<BR>尽管可以把这些功能相互分离开来,但为了简单明了,还是将它们放到Servlet中,只是由不同的方法进行分割。<BR>源代码如下:</P><PRE class=programlisting> 	 <BR>	/**<BR>	 * 本例程演示了通过Web上传文件过程中的进度显示。您可以对本例程进行任何修改和使用。<BR>	 *<BR>	 * 如需要转载,请注明作者。<BR>	 *<BR>	 * 作者: 刘作晨<BR>	 * <BR>	 */	<BR>	package liuzuochen.sample.upload;<BR>	<BR>	import java.io.File;<BR>	import java.io.IOException;<BR>	import java.util.List;<BR>	<BR>	<BR>	import javax.servlet.ServletException;<BR>	import javax.servlet.http.HttpServletRequest;<BR>	import javax.servlet.http.HttpServletResponse;<BR>	<BR>	import org.apache.commons.fileupload.FileItem;<BR>	import org.apache.commons.fileupload.FileUploadException;<BR>	import org.apache.commons.fileupload.disk.DiskFileItemFactory;<BR>	import org.apache.commons.fileupload.servlet.*;<BR>	<BR>	<BR>	public class BackGroundService extends javax.servlet.http.HttpServlet implements			javax.servlet.Servlet {<BR>	<BR>		public static final String UPLOAD_DIR = "/upload";<BR>		public static final String DEFAULT_UPLOAD_FAILURE_URL = "./result.jsp";<BR>	<BR>		public BackGroundService() {<BR>			super();<BR>		}<BR>	<BR>	<BR>		protected void doGet(HttpServletRequest request,							 HttpServletResponse response) throws ServletException,				IOException {<BR>			doPost(request, response);<BR>		}	<BR>		/**<BR>		 * 从文件路径中取出文件名<BR>		 */<BR>		private String takeOutFileName(String filePath) {<BR>			int pos = filePath.lastIndexOf(File.separator);<BR>			if (pos &gt; 0) {<BR>				return filePath.substring(pos + 1);<BR>			} else {<BR>				return filePath;<BR>			}<BR>		}<BR>	<BR>		/**<BR>		 * 从request中取出FileUploadStatus Bean<BR>		 */<BR>		public static FileUploadStatus getStatusBean(<BR>				HttpServletRequest request) {<BR>			BeanControler beanCtrl = BeanControler.getInstance();<BR>			return beanCtrl.getUploadStatus(request.getRemoteAddr());<BR>		}	<BR>		/**<BR>		 * 把FileUploadStatus Bean保存到类控制器BeanControler<BR>		 */<BR>		public static void saveStatusBean(				HttpServletRequest request,				FileUploadStatus statusBean) {<BR>			statusBean.setUploadAddr(request.getRemoteAddr());<BR>			BeanControler beanCtrl = BeanControler.getInstance();<BR>			beanCtrl.setUploadStatus(statusBean);<BR>		}<BR>	<BR>		/**<BR>		 * 删除已经上传的文件<BR>		 */<BR>		private void deleteUploadedFile(HttpServletRequest request) {<BR>			FileUploadStatus satusBean = getStatusBean(request);<BR>			for (int i = 0; i &lt; satusBean.getUploadFileUrlList().size(); i++) {<BR>				File uploadedFile = new File(request.getRealPath(UPLOAD_DIR) +											 File.separator +											 satusBean.getUploadFileUrlList().											 get(i));<BR>				uploadedFile.delete();<BR>			}<BR>			satusBean.getUploadFileUrlList().clear();<BR>			satusBean.setStatus("删除已上传的文件");<BR>			saveStatusBean(request, satusBean);<BR>		}<BR>	<BR>		/**<BR>		 * 上传过程中出错处理<BR>		 */<BR>		private void uploadExceptionHandle(				HttpServletRequest request,				String errMsg) throws ServletException, IOException {<BR>			//首先删除已经上传的文件<BR>			deleteUploadedFile(request);<BR>			FileUploadStatus satusBean = getStatusBean(request);<BR>			satusBean.setStatus(errMsg);<BR>			saveStatusBean(request, satusBean);<BR>		}<BR>	<BR>		/**<BR>		 * 初始化文件上传状态Bean<BR>		 */<BR>		private FileUploadStatus initStatusBean(HttpServletRequest<BR>				request) {<BR>			FileUploadStatus satusBean = new FileUploadStatus();<BR>			satusBean.setStatus("正在准备处理");<BR>			satusBean.setUploadTotalSize(request.getContentLength());<BR>			satusBean.setProcessStartTime(System.currentTimeMillis());<BR>			satusBean.setBaseDir(request.getContextPath() + UPLOAD_DIR);<BR>			return satusBean;<BR>		}<BR>	<BR>		/**<BR>		 * 处理文件上传<BR>		 */<BR>		private void processFileUpload(HttpServletRequest request,<BR>								<BR>	   HttpServletResponse response) throws				ServletException, IOException {<BR>			DiskFileItemFactory factory = new DiskFileItemFactory();<BR>			//设置内存缓冲区,超过后写入临时文件<BR>			factory.setSizeThreshold(10240000);<BR>			//设置临时文件存储位置<BR>			factory.setRepository(new File(request.getRealPath("/upload/temp")));<BR>			ServletFileUpload upload = new ServletFileUpload(factory);<BR>			//设置单个文件的最大上传值<BR>			upload.setFileSizeMax(102400000);<BR>			//设置整个request的最大值<BR>			upload.setSizeMax(102400000);<BR>			upload.setProgressListener(new FileUploadListener(request));<BR>			//保存初始化后的FileUploadStatus Bean<BR>			saveStatusBean(request, initStatusBean(request));<BR>	<BR>			String forwardURL = "";<BR>			try {<BR>				List items = upload.parseRequest(request);<BR>				//获得返回url<BR>				for (int i = 0; i &lt; items.size(); i++) {<BR>					FileItem item = (FileItem) items.get(i);<BR>					if (item.isFormField()) {<BR>						forwardURL = item.getString();<BR>						break;<BR>					}<BR>				}<BR>				//处理文件上传<BR>				for (int i = 0; i &lt; items.size(); i++) {<BR>					FileItem item = (FileItem) items.get(i);<BR>	<BR>					//取消上传<BR>					if (getStatusBean(request).getCancel()) {<BR>						deleteUploadedFile(request);<BR>						break;<BR>					}<BR>					//保存文件<BR>					else if (!item.isFormField() &amp;&amp; item.getName().length() &gt; 0) {<BR>						String fileName = takeOutFileName(item.getName());<BR>						File uploadedFile = new File(request.getRealPath(UPLOAD_DIR) +<BR>													 File.separator + fileName);						item.write(uploadedFile);						//更新上传文件列表						FileUploadStatus <BR>satusBean =								getStatusBean(request);					<BR>	satusBean.getUploadFileUrlList().add(fileName);<BR>						saveStatusBean(request, satusBean);<BR>						Thread.sleep(500);<BR>					}<BR>				}<BR>	<BR>			} catch (FileUploadException e) {<BR>				uploadExceptionHandle(request, "上传文件时发生错误:" + e.getMessage());<BR>			} catch (Exception e) {<BR>				uploadExceptionHandle(request, "保存上传文件时发生错误:" + e.getMessage());<BR>			}<BR>			if (forwardURL.length() == 0) {<BR>				forwardURL = DEFAULT_UPLOAD_FAILURE_URL;<BR>			}<BR>			request.getRequestDispatcher(forwardURL).forward(request, response);<BR>		}<BR>	<BR>		/**<BR>		 * 回应上传状态查询<BR>		 */<BR>		private void responseStatusQuery(HttpServletRequest request,<BR>									<BR>			  HttpServletResponse response) throws				IOException {<BR>			response.setContentType("text/xml");<BR>			response.setCharacterEncoding("UTF-8");<BR>			response.setHeader("Cache-Control", "no-cache");<BR>			FileUploadStatus satusBean = getStatusBean(request);<BR>			response.getWriter().write(satusBean.toJSon());<BR>		}<BR>	<BR>		/**<BR>		 * 处理取消文件上传<BR>		 */<BR>		private void processCancelFileUpload(HttpServletRequest request,<BR>									<BR>		 HttpServletResponse response) throws				IOException {<BR>			FileUploadStatus satusBean = getStatusBean(request);<BR>			satusBean.setCancel(true);<BR>			saveStatusBean(request, satusBean);<BR>			responseStatusQuery(request, response);<BR>		}<BR>	<BR>		protected void doPost(HttpServletRequest request,<BR>							  HttpServletResponse response) throws ServletException,				IOException {<BR>			boolean isMultipart = ServletFileUpload.isMultipartContent(request);<BR>			if (isMultipart) {<BR>				processFileUpload(request, response);<BR>			} else {<BR>				request.setCharacterEncoding("UTF-8");<BR>	<BR>				if (request.getParameter("uploadStatus") != null) {<BR>					responseStatusQuery(request, response);<BR>				}<BR>				if (request.getParameter("cancelUpload") != null) {<BR>					processCancelFileUpload(request, response);<BR>				}<BR>	<BR>			}<BR>		}<BR>	}<BR>		</PRE>
<DIV>
<DIV>
<H3 class=title><A 
name=d20104></A>&nbsp;&nbsp;2.1.4.&nbsp;文件上传状态控制类(BeanControler)</H3></DIV>
<DIV><A 
href="http://blog.csdn.net/liuzuochen/archive/2007/02/28/1516522.aspx#d0">返回</A></DIV></DIV>
<P>   这是一个单例类,它的功能是为客户端保存文件上传状态,这里我没有使用Session来存储 
文件上传状态,<BR>因为对于AJAX这种异步调用,服务器会开启不同的Session,所以无法通过Session保存文件上传状态。<BR>我并不认为这种方法最好,如果有更好的方法,欢迎大家一起讨论。 
源代码如下:</P><PRE class=programlisting>		<BR>/**<BR>	 * 本例程演示了通过Web上传文件过程中的进度显示。您可以对本例程进行任何修改和使用。<BR>	 *<BR>	 * 如需要转载,请注明作者。<BR>	 *<BR>	 * 作者: 刘作晨<BR>	 * <BR>	 */	  <BR>		package liuzuochen.sample.upload;<BR>		<BR>		import java.util.Vector;<BR>		<BR>		public class BeanControler {<BR>			private static BeanControler beanControler = new BeanControler();<BR>			private Vector vector = new Vector();<BR>			private BeanControler() {<BR>			}<BR>		<BR>			public static BeanControler getInstance() {<BR>				return beanControler;<BR>			}<BR>		<BR>			/**<BR>			 * 取得相应FileUploadStatus类对象的存储位置<BR>			 */<BR>			private int indexOf(String strID) {<BR>				int nReturn = -1;<BR>				for (int i = 0; i &lt; vector.size(); i++) {<BR>					FileUploadStatus status = (FileUploadStatus) vector.elementAt(i);<BR>					if (status.getUploadAddr().equals(strID)) {<BR>						nReturn = i;<BR>						break;<BR>					}<BR>				}<BR>				return nReturn;<BR>			}<BR>			/**<BR>			 * 取得相应FileUploadStatus类对象<BR>			 */<BR>			public FileUploadStatus getUploadStatus(String strID) {<BR>				return (FileUploadStatus) vector.elementAt(indexOf(strID));<BR>			}<BR>			/**<BR>			 * 存储FileUploadStatus类对象<BR>			 */<BR>			public void setUploadStatus(FileUploadStatus status) {<BR>				int nIndex = indexOf(status.getUploadAddr());<BR>				if ( -1 == nIndex) {<BR>					vector.add(status);<BR>				} else {<BR>					vector.insertElementAt(status, nIndex);<BR>					vector.removeElementAt(nIndex + 1);<BR>				}<BR>			}<BR>			/**<BR>			 * 删除FileUploadStatus类对象<BR>			 */<BR>			public void removeUploadStatus(String strID){<BR>				int nIndex = indexOf(strID);<BR>				if(-1!=nIndex)<BR>					vector.removeElementAt(nIndex);<BR>			}<BR>		}	  	  </PRE>
<DIV>
<DIV>
<H2 class=title style="CLEAR: both"><A id=d202 
name=d202></A>&nbsp;2.2.&nbsp;客户端代码</H2></DIV></DIV>
<P>   客户端我们采用Prototype框架。</P>
<DIV>
<DIV>
<H3 class=title><A 
name=d20201></A>&nbsp;&nbsp;2.2.1.&nbsp;AjaxWrapper.js</H3></DIV>
<DIV><A 
href="http://blog.csdn.net/liuzuochen/archive/2007/02/28/1516522.aspx#d0">返回</A></DIV></DIV>
<P>   AjaxWrapper.js对Prototype进行了封装。 源代码如下:</P><PRE class=programlisting>	<BR>//类工具<BR>	var ClassUtils=Class.create();<BR>	ClassUtils.prototype={<BR>		_ClassUtilsName:'ClassUtils',<BR>		initialize:function(){<BR>		},<BR>		/**<BR>		 * 给类的每个方法注册一个对类对象的自我引用<BR>		 * @param reference 对类对象的引用<BR>		 */<BR>		registerFuncSelfLink:function(reference){<BR>			for (var n in reference) {<BR>				var item = reference[n];                        <BR>				if (item instanceof Function) <BR>					item.$ = reference;<BR>			}<BR>		}<BR>	}<BR>	//Ajax操作封装类:<BR>	//由于调用AjaxRequest类进行XMLHTTPRequest操作时,this引用(指向当前的对象)会出现了call stack问题,从而指向当前的对象。<BR>	//所以,对putRequest、callBackHandler、以及callback方法都要使用arguments.callee.$来获得正确的类对象引用<BR>	var AjaxWrapper=Class.create();<BR>	AjaxWrapper.prototype={<BR>		debug_flag:false,<BR>		xml_source:'',<BR>		/**<BR>		 * 初始化<BR>		 * @param isDebug 是否显示调试信息<BR>		 */<BR>		initialize:function(isDebug){<BR>			new ClassUtils().registerFuncSelfLink(this);<BR>			this.debug_flag=isDebug;<BR>			<BR>		},<BR>		/**<BR>		 * 以get的方式向server发送request<BR>		 * @param url<BR>		 * @param params<BR>		 * @param callBackFunction 发送成功后回调的函数或者函数名<BR>		 */<BR>		putRequest:function(url,params,callBackFunction){<BR>			var funcHolder=arguments.callee.$;<BR>			var xmlHttp = new Ajax.Request(url,<BR>				{<BR>					method: 'get', <BR>					parameters: params, <BR>					requestHeaders:['my-header-encoding','utf-8'],<BR>					onFailure: function(){<BR>						alert('对不起,网络通讯失败,请重新刷新!');<BR>					},<BR>					onSuccess: function(transport){<BR>					},<BR>					onComplete: function(transport){<BR>						funcHolder.callBackHandler.apply(funcHolder,[transport,callBackFunction]);<BR>					}<BR>				});<BR>		},<BR>		/**<BR>		 * 以post的方式向server发送xml请求<BR>		 * @param url<BR>		 * @param postDataBody<BR>		 * @param callBackFunction 发送成功后回调的函数或者函数名<BR>		 */<BR>		pushRequest:function(url,postDataBody,callBackFunction){<BR>			var funcHolder=arguments.callee.$;<BR>			var options={<BR>					method: 'post', <BR>					parameters:'',<BR>					requestHeaders:['my-header-encoding','utf-8'],<BR>					postBody: postDataBody,<BR>					onFailure: function(transport){<BR>						alert('对不起,网络通讯失败,请重新发送!');<BR>					},<BR>					onComplete: function(transport){<BR>						funcHolder.callBackHandler.apply(funcHolder,[transport,callBackFunction]);<BR>					}<BR>				};<BR>			var xmlHttp = new Ajax.Request(url,options);<BR>		},<BR>		/**<BR>		 * 远程调用的回调处理<BR>		 * @param transport xmlhttp的transport<BR>		 * @param callBackFunction 回调时call的方法,可以是函数也可以是函数名<BR>		 */<BR>		callBackHandler:function(transport,callBackFunction){<BR>			var funcHolder=arguments.callee.$;<BR>			if(transport.status!=200){<BR>				alert("获得回应失败,请求状态:"+transport.status);<BR>			}<BR>			else{<BR>				funcHolder.xml_source=transport.responseText;<BR>				if (funcHolder.debug_flag)<BR>					alert('call callback function');<BR>				if (typeof(callBackFunction)=='function'){<BR>					if (funcHolder.debug_flag){<BR>						alert('invoke callbackFunc');<BR>					}<BR>					callBackFunction(transport.responseText);<BR>				}<BR>				else{<BR>					if (funcHolder.debug_flag){<BR>						alert('evalFunc callbackFunc');<BR>					}<BR>					new execute().evalFunc(callBackFunction,transport.responseText);<BR>				}<BR>				if (funcHolder.debug_flag)<BR>					alert('end callback function');<BR>			}<BR>		},<BR>		//显示xml信息<BR>		showXMLResponse:function(){<BR>			var funcHolder=arguments.callee.$;<BR>			alert(funcHolder.xml_source);<BR>		}<BR>	}<BR>	<BR>	var XMLDomForAjax=Class.create();<BR>	XMLDomForAjax.prototype={<BR>		isDebug:false,<BR>		//dom节点类型常量<BR>		ELEMENT_NODE:1,<BR>		ATTRIBUTE_NODE:2,<BR>		TEXT_NODE:3,<BR>		CDATA_SECTION_NODE:4,<BR>		ENTITY_REFERENCE_NODE:5,<BR>		ENTITY_NODE:6,<BR>		PROCESSING_INSTRUCTION_NODE:7,<BR>		COMMENT_NODE:8,<BR>		DOCUMENT_NODE:9,<BR>		DOCUMENT_TYPE_NODE:10,<BR>		DOCUMENT_FRAGMENT_NODE:11,<BR>		NOTATION_NODE:12,<BR>		<BR>		initialize:function(isDebug){<BR>			new ClassUtils().registerFuncSelfLink(this);<BR>			this.isDebug=isDebug;<BR>		},<BR>		/**<BR>		 * 建立跨平台的dom解析器<BR>		 * @param xml xml字符串<BR>		 * @return dom解析器<BR>		 */<BR>		createDomParser:function(xml){<BR>			// code for IE<BR>			if (window.ActiveXObject){<BR>			  var doc=new ActiveXObject("Microsoft.XMLDOM");<BR>			  doc.async="false";<BR>			  doc.loadXML(xml);<BR>			}<BR>			// code for Mozilla, Firefox, Opera, etc.<BR>			else{<BR>			  var parser=new DOMParser();<BR>			  var doc=parser.parseFromString(xml,"text/xml");<BR>			}<BR>			return doc;<BR>		},<BR>		/**<BR>		 * 反向序列化xml到javascript Bean<BR>		 * @param xml xml字符串<BR>		 * @return javascript Bean<BR>		 */<BR>		deserializedBeanFromXML:function (xml){<BR>			var funcHolder=arguments.callee.$;<BR>			var doc=funcHolder.createDomParser(xml);<BR>			// documentElement总表示文档的root<BR>			var objDomTree=doc.documentElement;<BR>			var obj=new Object();<BR>			for (var i=0; i0){<BR>								objFieldValue[objFieldValue.length]=nodeText;<BR>							}<BR>						}<BR>						else{<BR>							objFieldValue=new Array();<BR>						}<BR>					}<BR>					else if (node.getAttribute('type')=='long' <BR>						|| node.getAttribute('type')=='java.lang.Long'<BR>						|| node.getAttribute('type')=='int'<BR>						|| node.getAttribute('type')=='java.lang.Integer'){						<BR>						objFieldValue=parseInt(nodeText);<BR>					}<BR>					else if (node.getAttribute('type')=='double' <BR>						|| node.getAttribute('type')=='float'<BR>						|| node.getAttribute('type')=='java.lang.Double'<BR>						|| node.getAttribute('type')=='java.lang.Float'){<BR>						<BR>						objFieldValue=parseFloat(nodeText);<BR>					}<BR>					else if (node.getAttribute('type')=='java.lang.String'){<BR>						objFieldValue=nodeText;<BR>					}<BR>					else{<BR>						objFieldValue=nodeText;<BR>					}<BR>					//赋值给对象<BR>					obj[node.getAttribute('name')]=objFieldValue;<BR>					if (funcHolder.isDebug){<BR>						alert(eval('obj.'+node.getAttribute('name')));<BR>					}<BR>				}<BR>				else if (node.nodeType == funcHolder.TEXT_NODE){<BR>					if (funcHolder.isDebug){<BR>						//alert('TEXT_NODE');<BR>					}<BR>					<BR>				}<BR>				else if (node.nodeType == funcHolder.CDATA_SECTION_NODE){<BR>					if (funcHolder.isDebug){<BR>						//alert('CDATA_SECTION_NODE');<BR>					}<BR>				}<BR>			}<BR>			return obj;<BR>		},<BR>		/**<BR>		 * 获得dom节点的text<BR>		 */<BR>		getNodeText:function (node) {<BR>			var funcHolder=arguments.callee.$;<BR>			// is this a text or CDATA node?<BR>			if (node.nodeType == funcHolder.TEXT_NODE || node.nodeType == funcHolder.CDATA_SECTION_NODE) {<BR>				return node.data;<BR>			}<BR>			var i;<BR>			var returnValue = [];<BR>			for (i = 0; i &lt; node.childNodes.length; i++) {<BR>				//采用递归算法<BR>				returnValue.push(funcHolder.getNodeText(node.childNodes[i]));<BR>			}<BR>			return returnValue.join('');<BR>		}<BR>	}<BR>	<BR>	//委托者类<BR>	var Dispatcher=Class.create();<BR>	Dispatcher.prototype={<BR>		name:'Dispatcher',<BR>		//对class中的每个function都赋值一个值为this的$属性<BR>		initialize:function(){<BR>			new ClassUtils().registerFuncSelfLink(this);<BR>		},<BR>		/**<BR>		 * 委托调用<BR>		 * @param caller 调用者,func的拥有者<BR>		 * @param func 如果是function对象,则使用Dispatcher对象自己的name作为参数;否则直接调用func<BR>		 */<BR>		dispatch:function(caller,func){<BR>			if (func instanceof Function){<BR>				var funcArguments=new Array();<BR>				funcArguments[0]=arguments.callee.$.name;<BR>				func.apply(caller,funcArguments);<BR>			}<BR>			else{<BR>				eval(func);<BR>			}<BR>		}<BR>	}<BR>	//祈祷者类<BR>	var Invoker=Class.create();<BR>	Invoker.prototype={<BR>		name:'Invoker',<BR>		initialize:function(){<BR>		},<BR>		invoke:function(showMsg){<BR>			alert(showMsg+"——this.name="+this.name);<BR>		}<BR>	}		</PRE>
<DIV>
<DIV>
<H3 class=title><A 
name=d20202></A>&nbsp;&nbsp;2.2.2.&nbsp;fileUpload.html</H3></DIV>
<DIV><A 
href="http://blog.csdn.net/liuzuochen/archive/2007/02/28/1516522.aspx#d0">返回</A></DIV></DIV>
<P>   fileUpload.html是文件上传界面。 源代码如下:</P><PRE class=programlisting><BR>		&lt;html&gt;<BR>		&lt;head&gt;<BR>		&lt;meta http-equiv="Content-Type" content="text/html; charset=GBK"&gt;<BR>		&lt;script type="text/javascript" src="./javascript/prototype.js"&gt;&lt;/script&gt;<BR>		&lt;script type="text/javascript" src="./javascript/AjaxWrapper.js"&gt;&lt;/script&gt;<BR>		&lt;link href="./css/fileUpload.css" type="text/css" rel="stylesheet"/&gt;<BR>		&lt;title&gt;文件上传&lt;/title&gt;<BR>		<BR>		&lt;/head&gt;<BR>		&lt;body&gt;<BR>		&lt;div id="controlPanel"&gt;<BR>			&lt;div id="readme"&gt;测试说明:&nbsp;&nbsp;最大上传量:100M,单个文件最大长度:100M&lt;/div&gt;<BR>			&lt;div id="uploadFileUrl"&gt;&lt;/div&gt;<BR>			<BR>			&lt;form id="fileUploadForm" name="fileUploadForm" action="./BackGroundService.action" <BR>				enctype="multipart/form-data" method="post"&gt;<BR>			&lt;input type="file" name="file" id="file" size="40"/&gt;&lt;br&gt;<BR>			&lt;input type="file" name="file" id="file" size="40"/&gt;&lt;br&gt;<BR>			&lt;input type="file" name="file" id="file" size="40"/&g

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -