Struts2 Ajax 上传文件,显示进度

大家可能以前用ajax上传文件时,是把form提交到<iframe></iframe>,HTML代码如下:

Html代码   收藏代码
  1. <form action="uploadAction.action"  enctype="multipart/form-data" id="fileform" name="fileform" method="post"  
  2.      target="upload-target">  
  3. <input type="file" value="浏览" name="upload" />  
  4. <input type="submit" value="提交"/>  
  5. </form>  
  6. <iframe id="upload-target"></iframe>  
<form action="uploadAction.action"  enctype="multipart/form-data" id="fileform" name="fileform" method="post"
     target="upload-target">
<input type="file" value="浏览" name="upload" />
<input type="submit" value="提交"/>
</form>
<iframe id="upload-target"></iframe>

  这样不用跳转页面就可以实现文件的上传,Action的代码如下:

Java代码   收藏代码
  1. public class UploadAction extends ActionSupport {  
  2.             //上传的文件  
  3.     private File upload;  
  4.     //上传文件的类型  
  5.     private String uploadContentType;  
  6.     上传文件的文件名  
  7.     private String uploadFileName;  
  8.       
  9.       
  10.       
  11.     //getter setter  
  12.     @Override  
  13.     public String execute() throws Exception {  
  14.         System.out.println(upload.length());  
  15.         FileOutputStream fos = new FileOutputStream(ServletActionContext.getServletContext().getRealPath("/") + uploadFileName);  
  16.         FileInputStream fis = new FileInputStream(upload);  
  17.         byte[] buffer = new byte[10240];  
  18.         int len = 0;  
  19.         double temp = 0;  
  20.         int total = fis.available();  
  21.         while((len = fis.read(buffer)) > 0){  
  22.             fos.write(buffer, 0, len);  
  23.             fos.flush();  
  24.               
  25.         }  
  26.         fis.close();  
  27.         fos.close();  
  28.         return SUCCESS;  
  29.     }  
public class UploadAction extends ActionSupport {
            //上传的文件
	private File upload;
	//上传文件的类型
	private String uploadContentType;
	上传文件的文件名
	private String uploadFileName;
	
	
	
	//getter setter
	@Override
	public String execute() throws Exception {
		System.out.println(upload.length());
		FileOutputStream fos = new FileOutputStream(ServletActionContext.getServletContext().getRealPath("/") + uploadFileName);
		FileInputStream fis = new FileInputStream(upload);
		byte[] buffer = new byte[10240];
		int len = 0;
		double temp = 0;
		int total = fis.available();
		while((len = fis.read(buffer)) > 0){
			fos.write(buffer, 0, len);
			fos.flush();
			
		}
		fis.close();
		fos.close();
		return SUCCESS;
	}

 

 这样就可以在一个页面上上传文件了。但怎么显示上传文件的进度呢。一开始我的想法是在Action增加一个perc属性,该属性存放着上传的进度,再增加一个方法,输出perc的值.

Java代码   收藏代码
  1.    private double perc;  
  2.   
  3. blic String ajaxGetPerc() throws Exception{  
  4.   
  5. HttpServletResponse response = ServletActionContext.getResponse();  
  6. PrintWriter writer = null;  
  7. writer = response.getWriter();  
  8. writer.println(perc);  
  9. writer.flush();  
  10. writer.close();  
  11. return null;  
     private double perc;

public String ajaxGetPerc() throws Exception{
	
		HttpServletResponse response = ServletActionContext.getResponse();
		PrintWriter writer = null;
		writer = response.getWriter();
		writer.println(perc);
		writer.flush();
		writer.close();
		return null;
	}

  最后试验了一下,发现该方法行不通,能上传文件,使用ajax返回的进度值始终是0;

  想想第二种方法,使用线程的方式上传文件,并把进度值保存在session中, 并且要使用两个页面,一个页面负责文件的上传,一个负责显示进度。详细代码如下:

upload.jsp负责文件的上传,是一个很普通的HTML页面

Html代码   收藏代码
  1. <body>  
  2. <h1>文件上传</h1>  
  3. <form action="uploadAction.action"  enctype="multipart/form-data" id="fileform" name="fileform" method="post"  
  4.     >  
  5. <input type="file" value="浏览" name="upload" />  
  6. <input type="submit" value="提交"/>  
  7. </form>  
  8. </body>  
<body>
<h1>文件上传</h1>
<form action="uploadAction.action"  enctype="multipart/form-data" id="fileform" name="fileform" method="post"
    >
<input type="file" value="浏览" name="upload" />
<input type="submit" value="提交"/>
</form>
</body>

  showPerc.jsp使用ajax间隔的查询进度值

Html代码   收藏代码
  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2. <%@ page language="java" contentType="text/html; charset=UTF-8"  
  3.     pageEncoding="UTF-8"%>  
  4. <%  
  5.     String path = request.getContextPath();  
  6.  %>  
  7. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
  8. <html xmlns="http://www.w3.org/1999/xhtml">  
  9. <head>  
  10. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />  
  11. <script type="text/javascript" src="<%=path %>/js/jquery-1.3.2.min.js"></script>  
  12. <script type="text/javascript">  
  13. var xmlHttp ;  
  14. function createXMLHttp(){  
  15.     if(window.ActiveXObject){  
  16.         xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");  
  17.     }  
  18.     else{  
  19.         xmlHttp = new XMLHttpRequest() ;  
  20.     }  
  21. }  
  22.   
  23. function ajaxSend(){  
  24.     createXMLHttp() ;  
  25.       
  26.     var url ="<%=path %>/getUploadPerc.action?random=" + Math.random(); ;  
  27.     xmlHttp.onreadystatechange = handler ;  
  28.     xmlHttp.open("GET",url,true) ;  
  29.     //xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");  
  30.     xmlHttp.send(null) ;  
  31. }  
  32. function handler(){  
  33.  if(xmlHttp.readyState == 4)     {  
  34.   if(xmlHttp.status == 200)      {  
  35.         var percent = xmlHttp.responseText ;  
  36.         document.getElementById('pre').innerHTML = percent;  
  37.         var t = setTimeout("ajaxSend()",100) ;  
  38.          
  39.         if(percent == 100){  
  40.             alert('上传完成');  
  41.             clearTimeout(t);  
  42.         }  
  43.   }  
  44.  }  
  45.  return true;  
  46. }  
  47.   
  48. window.onload = function(){  
  49.     ajaxSend();   
  50. }  
  51. </script>  
  52. <title>文件上传</title>  
  53. </head>  
  54. <body>  
  55. <h1>进度条</h1>  
  56. <div id="pre"></div>  
  57. </body>  
  58. </html>  
<?xml version="1.0" encoding="UTF-8" ?>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	String path = request.getContextPath();
 %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script type="text/javascript" src="<%=path %>/js/jquery-1.3.2.min.js"></script>
<script type="text/javascript">
var xmlHttp ;
function createXMLHttp(){
    if(window.ActiveXObject){
        xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
    else{
        xmlHttp = new XMLHttpRequest() ;
    }
}

function ajaxSend(){
    createXMLHttp() ;
    
    var url ="<%=path %>/getUploadPerc.action?random=" + Math.random(); ;
    xmlHttp.onreadystatechange = handler ;
    xmlHttp.open("GET",url,true) ;
    //xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
    xmlHttp.send(null) ;
}
function handler(){
 if(xmlHttp.readyState == 4)     {
  if(xmlHttp.status == 200)      {
        var percent = xmlHttp.responseText ;
        document.getElementById('pre').innerHTML = percent;
        var t = setTimeout("ajaxSend()",100) ;
       
        if(percent == 100){
            alert('上传完成');
        	clearTimeout(t);
        }
  }
 }
 return true;
}

window.onload = function(){
	ajaxSend();	
}
</script>
<title>文件上传</title>
</head>
<body>
<h1>进度条</h1>
<div id="pre"></div>
</body>
</html>

 Action代码

Java代码   收藏代码
  1. package com.struts.action;  
  2.   
  3. import java.io.*;  
  4.   
  5. import javax.servlet.http.HttpServletResponse;  
  6. import javax.servlet.http.HttpSession;  
  7.   
  8. import org.apache.struts2.ServletActionContext;  
  9.   
  10. import com.opensymphony.xwork2.ActionSupport;  
  11.   
  12. public class UploadAction extends ActionSupport {  
  13.   
  14.     private String title;  
  15.       
  16.     private File upload;  
  17.       
  18.     private String uploadContentType;  
  19.       
  20.     private String uploadFileName;  
  21.       
  22.     private String savePath;  
  23.   
  24.     private double perc;  
  25.       
  26.     public double getPerc() {  
  27.         return perc;  
  28.     }  
  29.   
  30.     public void setPerc(double perc) {  
  31.         this.perc = perc;  
  32.     }  
  33.   
  34.     public String getTitle() {  
  35.         return title;  
  36.     }  
  37.   
  38.     public void setTitle(String title) {  
  39.         this.title = title;  
  40.     }  
  41.   
  42.     public File getUpload() {  
  43.         return upload;  
  44.     }  
  45.   
  46.     public void setUpload(File upload) {  
  47.         this.upload = upload;  
  48.     }  
  49.   
  50.     public String getUploadContentType() {  
  51.         return uploadContentType;  
  52.     }  
  53.   
  54.     public void setUploadContentType(String uploadContentType) {  
  55.         this.uploadContentType = uploadContentType;  
  56.     }  
  57.   
  58.     public String getUploadFileName() {  
  59.         return uploadFileName;  
  60.     }  
  61.   
  62.     public void setUploadFileName(String uploadFileName) {  
  63.         this.uploadFileName = uploadFileName;  
  64.     }  
  65.   
  66.     public String getSavePath() {  
  67.         return savePath;  
  68.     }  
  69.   
  70.     public void setSavePath(String savePath) {  
  71.         this.savePath = savePath;  
  72.     }  
  73.       
  74.     @Override  
  75.     public String execute() throws Exception {  
  76.         System.out.println(upload.length());  
  77.         File toFile = new File(ServletActionContext.getServletContext().getRealPath("/") + uploadFileName);  
  78.         HttpSession session = ServletActionContext.getRequest().getSession();  
  79.         session.setAttribute("perc"0);  
  80.         UploadThread uploadThread = new UploadThread(upload,toFile,session);  
  81.         Thread thread = new Thread(uploadThread);  
  82.         thread.start();  
  83.         return SUCCESS;  
  84.     }  
  85.       
  86.     public String ajaxGetPerc() throws Exception{  
  87.         HttpSession session = ServletActionContext.getRequest().getSession();  
  88.         System.out.println("session perc------" + session.getAttribute("perc"));  
  89.         //ServletActionContext.getResponse().getOutputStream().println((String)session.getAttribute("perc"));  
  90.         HttpServletResponse response = ServletActionContext.getResponse();  
  91.         PrintWriter writer = null;  
  92.         writer = response.getWriter();  
  93.         int perc = (Integer)session.getAttribute("perc");  
  94.         writer.println(perc);  
  95.         writer.flush();  
  96.         writer.close();  
  97.         return null;  
  98.     }  
  99. }  
  100.   
  101. /** 
  102.  *  
  103.  *  
  104.  * 因为原本文件上传完才能跳转,故在一个线程中上传文件,加速跳转到showPerc.jsp去显示进度. 
  105.  * 
  106.  */  
  107. class UploadThread implements Runnable {  
  108.     //在当前线程中上传的文件.  
  109.     private File from ;  
  110.     //保存到服务器硬盘上的位置.  
  111.     private File to ;  
  112.     //HttpSession需要传递过来,直接以ServletActionContext.getRequest.getSession将会抛出NullPointerException.  
  113.     private HttpSession httpSession;  
  114.     //构造方法,用来传址.  
  115.     public UploadThread(File from, File to , HttpSession httpSession) {  
  116.         this.from = from;  
  117.         this.to = to;  
  118.         this.httpSession = httpSession;  
  119.     }  
  120.     //线程中处理上传.  
  121.     @Override  
  122.     public void run() {  
  123.         copy(from, to , httpSession);  
  124.     }  
  125.       
  126.     //自己实现的上传方法,因为需要计算进度,所以无法使用IOUtils.copy(InputStream in , OutputStream out)方法了.  
  127.     /** 
  128.      * @param from           需要上传的文件. 
  129.      * @param to             保存到服务器上的位置. 
  130.      * @param httpSession    得到当前窗口的session. 
  131.      */  
  132.     public void copy(File from, File uploadFile , HttpSession httpSession) {  
  133.         InputStream fis;  
  134.         try {  
  135.             fis = new FileInputStream(from);  
  136.           
  137.         OutputStream fos = new FileOutputStream(uploadFile);  
  138.         byte[] buffer = new byte[10240];  
  139.         int len = 0;  
  140.         double temp = 0;  
  141.         int perc = 0;  
  142.         int total = fis.available();  
  143.         while((len = fis.read(buffer)) > 0){  
  144.             fos.write(buffer, 0, len);  
  145.             fos.flush();  
  146.             temp += len;  
  147.               
  148.             perc = (int)(temp / total * 100);  
  149.             //System.out.println(perc + "----------------" + total);  
  150.             httpSession.setAttribute("perc", perc);  
  151.             Thread.sleep(200);  
  152.         }  
  153.         fis.close();  
  154.         fos.close();  
  155.         } catch (FileNotFoundException e) {  
  156.             e.printStackTrace();  
  157.         } catch (IOException e) {  
  158.             e.printStackTrace();  
  159.         } catch (InterruptedException e) {  
  160.             e.printStackTrace();  
  161.         }  
  162.     }  
  163.       
  164. }  
package com.struts.action;

import java.io.*;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;

public class UploadAction extends ActionSupport {

	private String title;
	
	private File upload;
	
	private String uploadContentType;
	
	private String uploadFileName;
	
	private String savePath;

	private double perc;
	
	public double getPerc() {
		return perc;
	}

	public void setPerc(double perc) {
		this.perc = perc;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public File getUpload() {
		return upload;
	}

	public void setUpload(File upload) {
		this.upload = upload;
	}

	public String getUploadContentType() {
		return uploadContentType;
	}

	public void setUploadContentType(String uploadContentType) {
		this.uploadContentType = uploadContentType;
	}

	public String getUploadFileName() {
		return uploadFileName;
	}

	public void setUploadFileName(String uploadFileName) {
		this.uploadFileName = uploadFileName;
	}

	public String getSavePath() {
		return savePath;
	}

	public void setSavePath(String savePath) {
		this.savePath = savePath;
	}
	
	@Override
	public String execute() throws Exception {
		System.out.println(upload.length());
		File toFile = new File(ServletActionContext.getServletContext().getRealPath("/") + uploadFileName);
		HttpSession session = ServletActionContext.getRequest().getSession();
		session.setAttribute("perc", 0);
		UploadThread uploadThread = new UploadThread(upload,toFile,session);
		Thread thread = new Thread(uploadThread);
		thread.start();
		return SUCCESS;
	}
	
	public String ajaxGetPerc() throws Exception{
		HttpSession session = ServletActionContext.getRequest().getSession();
		System.out.println("session perc------" + session.getAttribute("perc"));
		//ServletActionContext.getResponse().getOutputStream().println((String)session.getAttribute("perc"));
		HttpServletResponse response = ServletActionContext.getResponse();
		PrintWriter writer = null;
		writer = response.getWriter();
		int perc = (Integer)session.getAttribute("perc");
		writer.println(perc);
		writer.flush();
		writer.close();
		return null;
	}
}

/**
 * 
 * 
 * 因为原本文件上传完才能跳转,故在一个线程中上传文件,加速跳转到showPerc.jsp去显示进度.
 *
 */
class UploadThread implements Runnable {
	//在当前线程中上传的文件.
	private File from ;
	//保存到服务器硬盘上的位置.
	private File to ;
	//HttpSession需要传递过来,直接以ServletActionContext.getRequest.getSession将会抛出NullPointerException.
	private HttpSession httpSession;
	//构造方法,用来传址.
	public UploadThread(File from, File to , HttpSession httpSession) {
		this.from = from;
		this.to = to;
		this.httpSession = httpSession;
	}
	//线程中处理上传.
	@Override
	public void run() {
		copy(from, to , httpSession);
	}
	
	//自己实现的上传方法,因为需要计算进度,所以无法使用IOUtils.copy(InputStream in , OutputStream out)方法了.
	/**
	 * @param from           需要上传的文件.
	 * @param to             保存到服务器上的位置.
	 * @param httpSession    得到当前窗口的session.
	 */
	public void copy(File from, File uploadFile , HttpSession httpSession) {
		InputStream fis;
		try {
			fis = new FileInputStream(from);
		
		OutputStream fos = new FileOutputStream(uploadFile);
		byte[] buffer = new byte[10240];
		int len = 0;
		double temp = 0;
		int perc = 0;
		int total = fis.available();
		while((len = fis.read(buffer)) > 0){
			fos.write(buffer, 0, len);
			fos.flush();
			temp += len;
			
			perc = (int)(temp / total * 100);
			//System.out.println(perc + "----------------" + total);
			httpSession.setAttribute("perc", perc);
			Thread.sleep(200);
		}
		fis.close();
		fos.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
}

  struts.xml配置文件

Java代码   收藏代码
  1. <pre name="code" class="xml"> <action name="uploadAction" class="com.struts.action.UploadAction">  
  2. <result>/showloadbar.jsp</result>  
  3. <result name="input">/upload.jsp</result>  
  4. <interceptor-ref name="fileUpload">  
  5. <param name="allowedTypes">image/bmp,image/png,image/gif,image/jpeg</param>  
  6. <param name="maximumSize">20000000000</param>  
  7. </interceptor-ref>  
  8. <interceptor-ref name="defaultStack"/>  
  9. </action>  
  10. <action name="getUploadPerc" class="com.struts.action.UploadAction" method="ajaxGetPerc">  
  11. </action></pre>  
  12.    

  
  
Xml代码   收藏代码
  1.  <action name="uploadAction" class="com.struts.action.UploadAction">  
  2. <result>/showloadbar.jsp</result>  
  3. <result name="input">/upload.jsp</result>  
  4. <interceptor-ref name="fileUpload">  
  5. <param name="allowedTypes">image/bmp,image/png,image/gif,image/jpeg</param>  
  6. <param name="maximumSize">20000000000</param>  
  7. </interceptor-ref>  
  8. <interceptor-ref name="defaultStack"/>  
  9. </action>  
  10. <action name="getUploadPerc" class="com.struts.action.UploadAction" method="ajaxGetPerc">  
  11. </action>  
 

  在这里我设置只能上传图片文件.

  可以上传文件,并能显示进度。但这里使用session存取进度值,会加重服务器的负担。各位有什么好的方法可以告诉我。谢谢

原文链接:http://hzl7652.iteye.com/blog/430061

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值