struts2下实现上传文件进度条

首先用EasyUI做界面:

<div id="loading2">
		<div class="inputdiv" >
			<img class="prtspan span_1" src="images/loading.gif"/>
			<h3 class="prtspan span_1" >war包正在部署,请稍候......</h3>
		</div>
	</div> 
<div id="loading1" style="display:none;">
                        <div id="loading" class="easyui-progressbar" style="width:700px;"></div>
</div> 

前端主要的js代码:

//定时器:文件上传是否完成了
var _finished = false;
function update_file_percent(){
if(_finished) return;
 $.get("deploy/searchWar.action",{} 
          ,function(data,textStatus){
           if(data=="100" || data==100){
              $('#loading').progressbar('setValue',0); 
              $('#loading1').css("display","none");
            $('#loading2').window('open'); 
              return;
           }
           $('#loading').progressbar('setValue', parseInt(data)); //返回的data包含换行符,必须要转成数字,否则进度条出不来颜色
            setTimeout("update_file_percent()", 1000); 
          });
}

//部署应用程序
function list_to_deploy_app(){
	$("#btnAddWar").click(function(){
            _finished = false;
             $("btnAddWar").attr("disabled","true"); 
               $('#loading').progressbar('setValue', 0); 
               $('#loading1').css("display","block");
               
                $.post("deploy/addWar.action",{type:"first"},function(data,textStatus){
                    setTimeout("update_file_percent()", 1000); 
                    $('#addWar').form('submit', 
                        {    
                            url:"deploy/addWar.action",    
                            onSubmit: function(){    
                                $("#hip").val(ip);   
                                $("#hport").val(port); 
                            },
                            success:function(data){ 
                                 _finished = true;
                                 $('#loading2').window('close'); 
                                 $('#loading1').css("display","none");
                                 $('#loading').progressbar('setValue',0); 
                                var m_obj = JSON.parse(data); 
                                $("btnAddWar").attr("disabled","false"); 
                                if(m_obj && m_obj.success == true){
                                    messagebox_tip('war包' + $("#incontext").val() + '部署成功!');
                                }else{
                                    messagebox_tip('war包' + $("#incontext").val() + '部署失败!\n失败原因是:'+m_obj.message); 
                                }
                            }
                        }
                    );//form submit   
                    
           });
		}
	);
}



后端java代码:

需要自己写程序调用common-fileupload来处理上传的文件,但在代码调用upload.parseRequest(request)来处理时,返回了空的items 

我在网上看了很多帖子,最终总结出一个相对来说比较简单的方法:

自已新增一个servlet Filter,并且把它的filter次序放到struts2的filter次序之前

将如下内容放在web.xml文件中其他filter的前面:

<!-- file filter -->
<filter>
    <filter-name>AuthFilter</filter-name>
    <filter-class>com.southgis.scout.hub.action.deploy.AuthFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>AuthFilter</filter-name>
<url-pattern>/deploy/addWar.action</url-pattern>
</filter-mapping>

新建的Filter的代码如下:

package com.southgis.scout.hub.action.deploy;
import java.io.IOException;   

import javax.servlet.Filter;   
import javax.servlet.FilterChain;   
import javax.servlet.FilterConfig;   
import javax.servlet.ServletException;   
import javax.servlet.ServletRequest;   
import javax.servlet.ServletResponse;   
import javax.servlet.http.HttpServletRequest;   


import org.apache.struts2.dispatcher.StrutsRequestWrapper;

public class AuthFilter implements Filter {   
    
	 public void destroy() {   
	  
	 }   
	 
	 public void doFilter(ServletRequest request, ServletResponse response,  
		        FilterChain chain) throws IOException, ServletException {  
		       chain.doFilter(new StrutsRequestWrapper((HttpServletRequest) request), response);  
		   }  
	 
	 public void init(FilterConfig filterConfig) throws ServletException {   
		  
	 }   
	 
}

这里先用StrutsRequestWrapper来给他wrapper一次,这样在经过struts2的filter的时候就不会有问题了。为啥呢?可以自己看看这个类 
org.apache.struts2.dispatcher.Dispatcher里面的wrapRequest方法,有这么个判断: 
if (request instanceof StrutsRequestWrapper) {  
    return request;  
}  

非常给力的处理方式。


新建UploadListener.java 内容如下:

package com.southgis.scout.hub.action.deploy;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.fileupload.ProgressListener;

public class UploadListener implements ProgressListener {

	
	private HttpSession session1;  
	public UploadListener(HttpServletRequest request) {
	
		session1=request.getSession(false);  
	}

	public void update(long bytesRead, long contentLength, int items) {
		int percent = (int) (100 * (double) bytesRead / (double) contentLength);
		session1.setAttribute("read",String.valueOf(percent)); 
	}
}


处理文件上传核心代码DeployAction.java:

package com.southgis.scout.hub.action.deploy;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import javax.servlet.ServletException;
import javax.servlet.http.HttpSession;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.dispatcher.multipart.MultiPartRequestWrapper;

import com.alibaba.fastjson.JSONObject;
import com.southgis.scout.core.action.BaseAction;
import com.southgis.scout.core.util.HttpUtil;

@Namespace("/deploy")
public class DeployAction extends BaseAction {
	private static final long serialVersionUID = 1L;
	
	private void executePost() throws ServletException, IOException {
		String type=request.getParameter("type");
		if(type!=null){
			//第一次初始化session
			HttpSession session = request.getSession(false);
			if(session!=null)
			{
				session.invalidate();
			}
			session = request.getSession(true);
			return;
		}
			
		String filePath="";
		// 监听器
		UploadListener listener = new UploadListener(request);
		// Apache 上传工具
		DiskFileItemFactory factory = new DiskFileItemFactory();
		ServletFileUpload upload = new ServletFileUpload(factory);
		// 设置 listener
		upload.setProgressListener(listener);
		Map<String, String> map = new HashMap<String, String>();
		try {
			List itemList = upload.parseRequest(request);
			for (Iterator it = itemList.iterator(); it.hasNext();) {
				FileItem item = (FileItem) it.next();
				if (!item.isFormField()) {
					// 获取文件输出目录
					 String nowpath;             //当前tomcat的bin目录的路径 如 D:\java\software\apache-tomcat-6.0.14\bin
					 String tempdir;
					 nowpath=System.getProperty("user.dir");
					 tempdir=nowpath.replace("bin", "wars");  //把bin 文件夹变到 webapps文件里面 
					 //如果不存在tempdir则新建目录
						File myPath = new File(tempdir);
						if (!myPath.exists()) {
							myPath.mkdir();
						}
					//tempdir="F:/wars";测试用
					SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
					// 统一 Linux 与 windows 的路径分隔符
					String fileName =formatter.format(new Date()) + item.getName().replace("/", "\\");
					filePath=tempdir+"/"+fileName;
					File saved = new File(filePath);
					saved.getParentFile().mkdirs();
					item.write(saved);
				}
				else{
					map.put(item.getFieldName(),item.getString());
				}
			}
		} catch (Exception e) {
			outJsonResult(new JSONObject());
		}
		
		String url = "http://" + map.get("ip") + ":" + map.get("port") + "/plug/deploy/deploywar";
		String a="true";
		if(map.get("update")==null){
			a="false";
		}
		map.put("update", a);
		String result = HttpUtil.postFile(url, "attach", filePath, map);
		JSONObject jsonObj = JSONObject.parseObject(result);
		outJsonResult(jsonObj);
	}
	

	@Action("addWar")
	public void addWar() throws Exception {
		executePost();
	}
	
	@Action("searchWar")
	public void searchWar() throws Exception {
		response.setHeader("Cache-Control", "no-store");
		response.setHeader("Pragrma", "no-cache");
		response.setDateHeader("Expires", 0);response.setContentType("text/html;charset=UTF-8");
//如果不这样就会出现firefox 的jQuery.get返回object xmldocument的问题,或者你在jQuery.get中设置dataType为text
		HttpSession session = request.getSession(false);
		 String value=(String )session.getAttribute("read");
			if (value != null) {
			  
			    response.getWriter().println(value);
			}
			else{
				response.getWriter().println("0");
			}
	}

}

最后注意:

debug的时候可以用Fiddler抓包工具查看从后台get来的进度信息,但是如果你想体验进度条,则必须要关闭Fiddler。

否则就会出现浏览器上传文件,左下角提示上传百分之多少,然后完成,然后进度条才逐渐显示百分之几。这个问题困扰了我很久。一开始我还冤枉是Apache的commons-fileupload有问题:进度条信息只是针对服务器端保存文件的进度,而不是浏览器上传文件的进度。

其实是我错了,Apache的commons-fileupload确实能针对浏览器上传文件提供进度信息。看来Apache的东西确实牛逼。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值