zoukankan      html  css  js  c++  java
  • Servlet:htm+javascript+css+servlet (ajax)实现上传(能显示进度条)

    本示例需要commons-fileupload-1.3.jar和commons-io-2.4.jar的支持,新手请参阅无进度条的上传

    http://blog.csdn.net/tabactivity/article/details/11180631


    害羞确认您的环境配置成功后,下面开始编码:


    src/UploadStatus.java ,数据模型类

    package com.xieyuan;
    
    public class UploadStatus {
    
    	private long bytesRead;
    
    	private long contentLength;
    
    	private int items;
    
    	private long startTime = System.currentTimeMillis();
    
    	public long getBytesRead() {
    		return bytesRead;
    	}
    
    	public void setBytesRead(long bytesRead) {
    		this.bytesRead = bytesRead;
    	}
    
    	public long getContentLength() {
    		return contentLength;
    	}
    
    	public void setContentLength(long contentLength) {
    		this.contentLength = contentLength;
    	}
    
    	public int getItems() {
    		return items;
    	}
    
    	public void setItems(int items) {
    		this.items = items;
    	}
    
    	public long getStartTime() {
    		return startTime;
    	}
    
    	public void setStartTime(long startTime) {
    		this.startTime = startTime;
    	}
    
    }
    

    src/UploadListener.java,继承自ProgressListener,当使用commons_uploadfile组件上传时,调用组件类的方法可添加上传监听,组件就会不断调用UploadListener的update方法

    package com.xieyuan;
    
    import org.apache.commons.fileupload.ProgressListener;
    
    public class UploadListener implements ProgressListener {
    
    	private UploadStatus status;
    
    	public UploadListener(UploadStatus status) {
    		this.status = status;
    	}
    
    	public void update(long bytesRead, long contentLength, int items) {
    		status.setBytesRead(bytesRead);
    		status.setContentLength(contentLength);
    		status.setItems(items);
    		
    	}
    }
    

    src/UploadServlet.java,该类doPost方法用于处理上传,index.jsp后台会使用XmlHttpRequest调用本Servlet的doGet方法,从session中获取最新的上传数据情况

    package com.xieyuan;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.io.PrintWriter;
    import java.util.List;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.sound.sampled.AudioFormat.Encoding;
    
    import org.apache.commons.fileupload.DiskFileUpload;
    import org.apache.commons.fileupload.FileItem;
    import org.apache.commons.fileupload.disk.DiskFileItemFactory;
    import org.apache.commons.fileupload.servlet.ServletFileUpload;
    
    
    public class UploadServlet extends HttpServlet {
    
        //定义临时文件盒上传文件的存储路径
        private File uploadTemp=null;
        private File uploadPath=null;
        
        /**
         * Constructor of the object.
         */
        public UploadServlet() {
            super();
        }
    
        /**
         * Destruction of the servlet. <br>
         */
        public void destroy() {
            super.destroy(); // Just puts "destroy" string in log
            // Put your code here
        }
    
    
        /**
         * The doGet method of the servlet. <br>
         *
         * This method is called when a form has its tag value method equals to get.
         * 
         * @param request the request send by the client to the server
         * @param response the response send by the server to the client
         * @throws ServletException if an error occurred
         * @throws IOException if an error occurred
         */
        public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
             //禁用缓存,index.jsp后台会使用XmlHttpRequest调用本Servlet的doGet方法,从session中获取最新的上传数据情况
            response.setHeader("Cache-Control", "no-store");
            response.setHeader("Pragrma", "no-cache");
            response.setDateHeader("Expires", 0);
            response.setContentType("text/html;charset=utf-8");
            UploadStatus status = (UploadStatus) request.getSession(true)
                    .getAttribute("uploadStatus");
        
            if (status == null) {
                response.getWriter().println("没有上传信息");
                
                return;
            }
            long startTime = status.getStartTime();
            long currentTime = System.currentTimeMillis();
    
            // 已传输的时间 单位:s
            long time = (currentTime - startTime) / 1000 + 1;
    
            // 传输速度 单位:byte/s
            double velocity = ((double) status.getBytesRead()) / (double) time;
    
            // 估计总时间 单位:s
            double totalTime = status.getContentLength() / velocity;
    
            // 估计剩余时间 单位:s
            double timeLeft = totalTime - time;
    
            // 已完成的百分比
            int percent = (int) (100 * (double) status.getBytesRead() / (double) status
                    .getContentLength());
    
            // 已完成数 单位:M
            double length = ((double) status.getBytesRead()) / 1024 / 1024;
    
            // 总长度 单位:M
            double totalLength = ((double) status.getContentLength()) / 1024 / 1024;
    
            // 格式:百分比||已完成数(M)||文件总长度(M)||传输速率(K)||已用时间(s)||估计总时间(s)||估计剩余时间(s)||正在上传第几个文件
            String value = percent + "||" + length + "||" + totalLength + "||"
                    + velocity + "||" + time + "||" + totalTime + "||" + timeLeft
                    + "||" + status.getItems();
    
            response.getWriter().println(value);
        }
    
        /**
         * The doPost method of the servlet. <br>
         *
         * This method is called when a form has its tag value method equals to post.
         * 
         * @param request the request send by the client to the server
         * @param response the response send by the server to the client
         * @throws ServletException if an error occurred
         * @throws IOException if an error occurred
         */
        public void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            File file=null;
            String description=null;
            
            //设置响应格式(不设置请求格式,因为文件是二进制的,不能使用UTF-8格式化请求数据)
            response.setContentType("text/html;charset=utf-8");
            
            PrintWriter out=response.getWriter();
            out.println("<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">");
            out.println("<HTML>");
            out.println("<HEAD><TITLE>文件上传</TITLE></HEAD>");
            out.println("<BODY style='margin:50px'>");
            out.println("上传日志:<BR/>");
            
            UploadStatus status=new UploadStatus();
            UploadListener listener=new UploadListener(status);
            /*
             * 
             * 把 UploadStatus 放到 session 里,引用
               返回与此请求关联的当前HttpSession,如果没有当前会话和创造是真实的,返回一个新的会话。
              如果创建是假的,并要求有没有有效的HttpSession,这个方法返回null。
             */
            request.getSession(true).setAttribute("uploadStatus", status);
            
            //创建基于磁盘的工厂,针对大文件,临时文件将存储在磁盘
            DiskFileItemFactory factory=new DiskFileItemFactory();
            //设置缓冲区大小,超出该文件直接写入到磁盘的大小设置门槛。
            factory.setSizeThreshold(10240);  //这里默认10KB
            //设置用于大于配置的大小阈值设置的临时存储文件目录。
            factory.setRepository(uploadTemp);
            //创建一个文件上传的句柄
            ServletFileUpload upload=new ServletFileUpload(factory);
            //设置最大文件尺寸 ,这里是40MB        
            upload.setSizeMax(41943040);
            upload.setHeaderEncoding("utf-8");
            
            // 设置 listener
            upload.setProgressListener(listener);
            
            try {
                //将解析结果放在LIST中
                List<FileItem> list =upload.parseRequest(request);
                out.println("遍历所有的 FileItem ... <br/>");
                // 遍历 list 中所有的 FileItem
                for(FileItem item:list)
                {
                    // 如果是 文本域
                    if(item.isFormField())
                    {
                        if(item.getFieldName().equals("description1")||item.getFieldName().equals("description2"))
                        {
                                                
                            description = item.getString("UTF-8");    
                            System.out.println("遍历到 "+item.getFieldName()+" ... <br/>"+description+"<BR/>");    
                        }
                    }
                    else 
                    {
                        //否则为文件域,当getName为Null说明没有选则文件
                        if((item.getFieldName().equals("file1")||item.getFieldName().equals("file2"))
                                &&item.getName()!=null&&!item.getName().equals(""))
                        {
                            try 
                            {
                                // 统一 Linux 与 windows 的路径分隔符
                                String fileName = item.getName();
                                //fileName = fileName.substring(fileName.lastIndexOf("\"));
    
                                // 服务器端文件,放在 upload 文件夹下
                                file=new File(uploadPath,fileName);
                                if(!file.getParentFile().exists())
                                    file.getParentFile().mkdirs();
                                if(!file.exists())
                                    file.createNewFile();
                                
                                item.write(file);
                                
                                System.out.println("遍历到 "+fileName+" ... <br/>"+description+"<BR/>");    
                            } catch (Exception e) {
                                System.out.println("Request 上传失败!"+e.getMessage());
                            }
                            finally //总是立即删除保存表单字段内容的临时文件
                            {
                                item.delete();
                            }
                        }
                    }
                }
                System.out.println("Request 解析完毕,文件上传完毕!");
            } catch (Exception e) {
                System.out.println("Request 解析异常!"+e.getMessage());
            }
            out.flush();
            out.close();
        }
    
        
        /**
         * Initialization of the servlet. <br>
         *
         * @throws ServletException if an error occurs
         */
        public void init() throws ServletException {
    
            uploadPath=new File(this.getServletContext().getRealPath("upload"));
            if(!uploadPath.exists())
                uploadPath.mkdirs();        
            uploadTemp=new File(this.getServletContext().getRealPath("upload/temp"));
            if(!uploadTemp.exists())
                uploadTemp.mkdirs();
        }
    
    }
    
    
    

    web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app 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">
      <servlet>
        <description>This is the description of my J2EE component</description>
        <display-name>This is the display name of my J2EE component</display-name>
        <servlet-name>UploadServlet</servlet-name>
        <servlet-class>com.xieyuan.UploadServlet</servlet-class>
      </servlet>
      
      <servlet-mapping>
        <servlet-name>UploadServlet</servlet-name>
        <url-pattern>/servlet/UploadServlet</url-pattern>
      </servlet-mapping>
      <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
      </welcome-file-list>
      
    </web-app>
    

    WebRoot / index.jsp

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
      <head>
        <title>带进度条的文件上传</title>
        
        <style type="text/css">
        #progressBar{400px;height:12px;background:#FFFFFF;border:1px solid #000000;padding:1px;}
        #progressBarItem{30%;height:100%;background:#FF0000;}
        </style>
        <script type="text/JavaScript">
         <!--默认为已经完成上传操作-->
         var _finished=true;
         function $(obj)
         {
            return document.getElementById(obj);
         }
         <!--显示进度条等信息-->
         function showStatus()
          {
              _finished=false;
             $('status').style.display='block';
             $('progressBarItem').style.width='1%';
             $('btnSubmit').disabled=true;
             <!--隔1秒后执行一次-->
             setTimeout("requestStatus()",1000);
          }
          <!--发送请求获取文件上传状态-->
          function requestStatus()
          {
             if(_finished)
                   return;
             var req=createRequest();
             req.open("GET","servlet/UploadServlet");
             req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
             req.onreadystatechange=function(){callback(req);};
             //我们的实例在 open() 的第三个参数中使用了 "true"。该参数规定请求是否异步处理。
             //True 表示脚本会在 send() 方法之后继续执行,而不等待来自服务器的响应。
             
             req.send(null);
             setTimeout("requestStatus()",1000);
          }
        function createRequest()
        {
            if(window.XMLHttpRequest)//ns
            {
                return new XMLHttpRequest();
            }else//IE
            {
                try{
                    return new ActiveXObject("Msxml2.XMLHTTP");
                }catch(e){
                    return new ActiveXObject("Microsoft.XMLHTTP");
                }
            }
            return null;
        }
          function callback(req)
          {
                //请求结束后 
              if(req.readyState==4)
              {
                  //如果发生错误,则显示错误信息 
                 if(req.status!=200)
                 {
                    _debug("发生错误。 req.status: " + req.status + "");
                   return;
                 }
        
                var ss = req.responseText.split("||");
                
                // 格式:百分比||已完成数(M)||文件总长度(M)||传输速率(K)||已用时间(s)||估计总时间(s)||估计剩余时间(s)||正在上传第几个文件
                $('progressBarItem').style.width = '' + ss[0] + '%'; 
                $('statusInfo').innerHTML = '已完成百分比: ' + ss[0] + '% <br />已完成数(M): ' + ss[1] + '<br/>文件总长度(M): ' + ss[2] + '<br/>传输速率(K): ' + ss[3] + '<br/>已用时间(s): ' + ss[4] + '<br/>估计总时间(s): ' + ss[5] + '<br/>估计剩余时间(s): ' + ss[6] + '<br/>正在上传第几个文件: ' + ss[7];
            
                if(ss[1] == ss[2])
                {
                _finished = true;
                $('statusInfo').innerHTML += "<br/><br/><br/>上传已完成。";     
                $('btnSubmit').disabled = false;
                }
               _debug("status.jsp 返回值:" + req.responseText);
            
              }
          }
          function _debug(obj)
          {
            //var div=document.createElement("DIV");
            $('debug').innerHTML="[debug]:"+obj+"<br/>";             
            //document.body.appendChild(div);
            
          }
        </script>
      </head> 
      <body style="margin:50px">
         <iframe name="upload_iframe" width="0" height="0" frameborder="0" ></iframe>
          
          <form action="servlet/UploadServlet" method="post" enctype="multipart/form-data"
                target="upload_iframe" onsubmit="showStatus();">
             <p>上传文件:</p>
             文件1:<input type="file" name="file1" /><br/>
             描述:<input type="text" name="description1" /><br/>
             文件2:<input type="file" name="file2" /><br/>
            描述:<input type="text" name="description2" /><br/>
          <input type="submit" id="btnSubmit" value=" 上  传 " />  
          </form>
          <div id="status" style="display:none;position:relative;line-height:100%;opacity:1;">
               上传进度:
               <div id="progressBar" ><div id="progressBarItem" /></div>
               <div id="statusInfo" style="margin:10px 0px 0px 0px;"/>
          </div>
          <BR/>
          <div id="debug" />
      </body>
      </html>
    
    
    
    

    通过访问:http://127.0.0.1:8080/Test/   查看程序效果,如图

    System.out.println打印的运行情况


    至此,一个简单的上传程序就完成了。

  • 相关阅读:
    Error (10327): VHDL error at xd.vhd(17): can't determine definition of operator ""+"" -- found 0 pos
    FPGA 起脚nCEO/IO管教设置问题
    使用Cross-validation (CV) 调整Extreme learning Machine (ELM) 最优参数的实现(matlab)
    Tools that help you scrape web data----帮助你收集web数据的工具
    采集网页数据---Using Java
    使用正则表达式自动对文本按照字符排序
    Apriori算法实例----Weka,R, Using Weka in my javacode
    关于FP-Growth 算法一个很好的ppt-学习分享
    ARFF文件格式
    Weka-学习
  • 原文地址:https://www.cnblogs.com/xieyuan/p/3787498.html
Copyright © 2011-2022 走看看