java 文件上传显示进度

13年前
       实现功能:通过在页面中上传文件,到ftp服务器
       页面用得html标签  <input type="file"/>  在表单中,设置 表单,请求文件头,enctype="multipart/form-data",我用得apache fileUpload,结合 apache Ftp  ,代码很简单,网上到处都有,但是有点注意, fileUpload,是会再web服务器,创建一个temp目录,将文件读到临时目录,如果不显示设置临时目录,会再web服务器目录,也可以自己显示设置临时目录,   apache ftp 实际是读取临时目录流,到指定的 ftp 服务器主机地址,原来找了很多资料,想知道如何搞进度条,原来 在 apache fileUploade,有个监听器,可以监听 流每次读取的文件信息, org.apache.commons.fileupload。
/* pBytesRead  到目前为止读取文件的比特数
  * pContentLength 文件总大小
  * pItems 目前正在读取第几个文件
  */
public interface ProgressListener {
 public abstract void update(long pBytesRead  , long pContentLength , int i);
}
implement  这个接口,
在文件上传的时候
ServletFileUpload upload = new ServletFileUpload(factory);
   progressListen getBarListener = new progressListen(request);
   upload.setProgressListener(getBarListener);
有个问题一定要注意 ,一定要写在   ServletFileUpload   初始对象后面,不然,会读不到数据,这个要看源代码就知道,在upload.write()里面,有对getBarListener !=null 的判断,因此要写在 初始对象后面,我为这个事,发了不少的实际,
在页面方面,需要搞个ajax ,调用一个请求,请求里面能读取 到getBarListener   里面的update(),设置的数据,  用个windows.setTimeOut(,5000),不断调用,不能太快,太快的话,页面基本是白色的,反应不过来
2:上面用windows.setTimeOut实时性不是很强,但是如果要狠强的实时性,可以采用服务器推得技术,由服务器主动发现客户端,这就要去研究了哦, 
3:在html5  下解决就很容易了,html5是双工通信,长连接的
  下面是简易代码:
   
public class progressListen   implements ProgressListener {
    private HttpSession session;
 
   public progressListen(HttpServletRequest request)
   {
  this.session=request.getSession();
  this.session.setAttribute("fileAttr", "ttttttttttttt");
  
 
  
   }
 
 /* pBytesRead  到目前为止读取文件的比特数
  * pContentLength 文件总大小
  * pItems 目前正在读取第几个文件
  */
 public void update(long pBytesRead, long pContentLength, int pItems) {
 
 
  
  session.setAttribute("byte", String.valueOf(pBytesRead));
  session.setAttribute("pContentLength", String.valueOf(pContentLength));
  
  System.out.println("update="+String.valueOf(pBytesRead));
 }
}

public class ProgressServlet extends HttpServlet {
 /**
  * Constructor of the object.
  */
 public ProgressServlet() {
  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 {
  //response.setContentType("text/html");
  System.out.println("id="+request.getSession().getId());
  
  System.out.println("isNew="+request.getSession().isNew());
  
  PrintWriter out = response.getWriter();
  
 
  String b=(String)request.getSession().getAttribute("byte");
  String pContentLength=(String)request.getSession().getAttribute("pContentLength");
  String fileAttr=(String)request.getSession().getAttribute("fileAttr");
  
  System.out.println("bbb="+b);
  System.out.println("1212=="+pContentLength);
   
  out.println("<HTML>");
  out.println("  <HEAD><TITLE>A Servlet</TITLE></HEAD>");
  out.println("  <BODY>");
  out.println(request.getSession().getId());
   out.println(fileAttr);
   out.println("bb="+b);
   out.println("1212="+pContentLength);
      out.println("  </BODY>");
  out.println("</HTML>");
  out.flush();
  out.close();
 }
 /**
  * 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 {
            this.doGet(request, response);
 }
 /**
  * Initialization of the servlet. <br>
  *
  * @throws ServletException if an error occurs
  */
 public void init() throws ServletException {
  // Put your code here
 }
}
 
public class UploadFileAction extends HttpServlet {
 /**
  * Constructor of the object.
  */
 public UploadFileAction() {
  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 {
  
 
    response.reset();
  
 // response.setContentType("text/html"); application/octet-stream
       response.setContentType("application/x-download");
 // response.setContentType("application/octet-stream");
  
  
  
  String file_name=request.getParameter("file_name");
  
  System.out.println("file_name="+file_name);
  //response.setHeader("Content-Disposition","attachment;filename=" + file_name); 
 // response.addHeader("Content-Disposition","attachment;filename=" + file_name); 
  
  //加上下面的这句话,下载下来的图片,打开为空白,当是大小一样
  response.setHeader("Content-Disposition", "attachment;filename=\"" + file_name + "\"" );
  //response.setHeader("Cache-Control", "private");
   //setHeader("Cache-Control", "private");
  java.io.File  ff=new File("F:/java/apache-ftpserver-1.0.5/res/home/"+file_name);
  //构建下载文件的对象
 
      //获得文件的长度
  long filesize = ff.length();
      //设置输出格式
  //response.addHeader("content-type", "application/x-msdownload;");
  //response.addHeader("Content-Disposition", "attachment; filename=" + response.encodeURL(file_name));
    response.addHeader("content-length", Long.toString(filesize));
  //System.out.println("ssss="+ff.getAbsolutePath());
  //System.out.println("ssss="+ff.isFile());
  
 
 
  FTPClient  ftpClient=new FTPClient();
  ftpClient.connect("127.0.0.1", 2121);
  ftpClient.login("admin", "admin");
  ftpClient.enterLocalPassiveMode(); 
  ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
  ftpClient.addProtocolCommandListener(new PrintCommandListener(
                new PrintWriter(System.out)));
  FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_NT);  
        conf.setServerLanguageCode("zh");
     OutputStream outputStream=response.getOutputStream();
   
        boolean b = ftpClient.retrieveFile(file_name, outputStream);
     
     if(b)
      System.out.println("下载成功!");
     else
      System.out.println("下载失败!");
     outputStream.flush();
     outputStream.close();
  //FTPFile ftpFile=ftpClient.mlistFile(file_name);
 // System.out.println("ftpFile.isFile="+ftpFile.isFile());
      //  java.io.File  f=new File(file_name);
 // java.io.OutputStream  file=new FileOutputStream(f);
     //   System.out.println(ftpClient.printWorkingDirectory());
       
 //java.io.InputStream  input= ftpClient.retrieveFileStream(file_name);
          /*
  java.io.InputStream  input =new FileInputStream(ff);
     byte r[]=new byte[1024];
  OutputStream outputStream=response.getOutputStream();
         int c=-1;
        
  while((c=input.read(r))>0)
  {
   outputStream.write(r, 0, c);
  }
  outputStream.flush();
  
  
   outputStream.close();
   input.close();
   response.flushBuffer();
   */
  // response.sendRedirect("index.jsp");
  // outputStream.close();
   
   
  
  
  /*
  
  boolean b =ftpClient.retrieveFile(file_name, file);
  
     if(b)
      System.out.println("下载成功!");
     else
      System.out.println("下载失败!");
  */  
    
    //file.flush();
     //file.close();
    // response.flushBuffer();
    
  //outputStream.flush();
  
   
    // file.flush();
     //file.close();
    // ftpClient.logout();
     //ftpClient.disconnect();
     //outputStream.close();
     // response.flushBuffer();
  
 }
 /**
  * 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 {
 // response.setContentType("text/html");
  PrintWriter out = response.getWriter();
  response.setCharacterEncoding("GBK");
  out.println("uri="+request.getRequestURI());
  out.println("url="+request.getRequestURL());
  
  
  
  try
  {
  boolean   isMult=ServletFileUpload.isMultipartContent(request);
  if(isMult==true)  //说明是
  {
   DiskFileItemFactory  factory = new DiskFileItemFactory();
   ServletFileUpload upload = new ServletFileUpload(factory);
   progressListen getBarListener = new progressListen(request);
   upload.setProgressListener(getBarListener);
   
   List<FileItem> items = upload.parseRequest(request);  
   Iterator<FileItem> itr = items.iterator();   
   while (itr.hasNext()) {        
    FileItem item = (FileItem) itr.next(); 
    
    //检查当前项目是普通表单项目还是上传文件。       
    if (item.isFormField()) {
     //如果是普通表单项目,显示表单内容。 
     String fieldName = item.getFieldName();
     if (fieldName.equals("name"))
                          out.println("ssssss="+fieldName);     
     }
    else {  //如果是上传文件,显示文件名。   
      
     out.print("<br>");  
     
     File fullFile = new File(item.getName());
     
     out.print("<br>="+fullFile.getName()); 
     
     out.print("lujin="+fullFile.getAbsolutePath());
     
     out.print("<br>111="+fullFile.getPath());
     
    // item.write(fullFile);
     
     FTPClient  ftpClient=new FTPClient();
     
     ftpClient.connect("127.0.0.1", 2121);
     ftpClient.login("admin", "admin");
     out.print(ftpClient.getRemotePort());
     ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
     ftpClient.setControlEncoding("GBK");
     ftpClient.addProtocolCommandListener(new PrintCommandListener(
                              new PrintWriter(System.out)));
     //out.println(ftpClient.getReplyCode());
     //设置上传工作目录   不设置,默认 res\home
     //ftpClient.changeWorkingDirectory("/");     
    // FileInputStream  fileInputStream=new FileInputStream(fullFile);
     String newFileName="test_"+new Random().nextInt(10000)+".JPG";
       ftpClient.storeFile(newFileName,item.getInputStream());
     
       ftpClient.logout();
       ftpClient.disconnect();
       
       //上传的文件名
       out.print("the upload file name is " + newFileName);  
      // downFile(newFileName,out);
     }
    } 
   }
  }catch(Exception e)
  {
  e.printStackTrace(); 
  }
 }
 
 
 
 
 public void downFile(String remoteFileName,PrintWriter out ) throws Exception
 {
 
  FTPClient  ftpClient=new FTPClient();
  ftpClient.connect("127.0.0.1", 2121);
  ftpClient.login("admin", "admin");
  ftpClient.addProtocolCommandListener(new PrintCommandListener(
                new PrintWriter(System.out)));
  ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
  String fileName[]=ftpClient.listNames();
  
  java.io.File f=new File(".\\"+fileName[4]);
  System.out.println("本地路径="+f.getAbsolutePath());
  
    java.io.OutputStream  file=new FileOutputStream("./"+fileName[4]);
   file.flush();
  boolean b=ftpClient.retrieveFile("test_4258.jpeg", file);
  
    if(b)
     System.out.println("成功!");
    else
     System.out.println("失败!");
  
  file.flush();
  ftpClient.logout();
  ftpClient.disconnect();
  file.close();
  for (int i=0;i<fileName.length;i++)
  {out.println("<br>"); 
   out.println("fileName="+fileName[i]);
  }  
 }
 
 /**
  * Initialization of the servlet. <br>
  *
  * @throws ServletException if an error occurs
  */
 public void init() throws ServletException {
  // Put your code here
 }
}
 
<script type="text/javascript">
  function getBarPress()
  {
   var request=new XMLHttpRequest();
     var sendUrl="http://127.0.0.1:8080/webTest/servlet/ProgressServlet";
   request.open("GET", sendUrl);      
         request.onreadystatechange = function() {
                    if (request.readyState == 4) {
                        if (request.status == 200){
                          document.getElementById("forecasts").innerHTML = request.responseText;
                        }
                    //   getBarPress();
                    }
                };
                request.send(null);
               
       /**
 if(request.readyState==4)
 {
     if(request.status==200)
    {    
     alert(request.responseText);
    document.getElementById("xianShi").innerHTML = request.responseText;
       }    
 }
 
  request.send(null);
  **/
 
 
 window.setTimeout("getBarPress()",4000);
  }
 
  function  onbuttommit()
 {
    var formid=document.getElementById("uploadForm");
 formid.submit();
 
 window.setTimeout("getBarPress()", 7000);
 }
 
 </script>