springMVC 整合进度条

最终效果:



本文将使用   apache fileupload   ,spring MVC   jquery1.6x , bootstrap  实现一个带进度条的多文件上传,

由于fileupload 的局限,暂不能实现每个上传文件都显示进度条,只能实现一个总的进度条,效果如图,

此文我们假定你了解SPRING MVC   ,jquery   

bootstrap 可以到此下载:http://www.bootcss.com/

两个JAR包 :commons-fileupload-1.2.jar

                      commons-io-2.4.jar



1.jsp 页面


	1. <!DOCTYPE html>  
	2. <%@ page contentType="text/html;charset=UTF-8"%>    
	3. <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>    
	4. <html xmlns="http://www.w3.org/1999/xhtml">  
	5. <head>  
	6. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />  
	7. <script src="../js/jquery-1.6.4.js" type="text/javascript"></script>  
	8. <link rel="stylesheet" type="text/css" href="../css/bootstrap.css"/>  
	9. </head>  
	10. <body>  
	11.         <form id='fForm' class="form-actions form-horizontal" action="../upload.html"   
	12.               encType="multipart/form-data" target="uploadf" method="post">  
	13.                  <div class="control-group">  
	14.                     <label class="control-label">上传文件:</label>  
	15.                     <div class="controls">  
	16.                         <input type="file"  name="file" style="width:550">  
	17.                               
	18.                     </div>  
	19.                     <div class="controls">  
	20.                         <input type="file"  name="file" style="width:550">  
	21.                     </div>  
	22.                     <div class="controls">  
	23.                         <input type="file"  name="file" style="width:550">  
	24.                     </div>  
	25.                     <label class="control-label">上传进度:</label>  
	26.                     <div class="controls">  
	27.                         <div  class="progress progress-success progress-striped" style="width:50%">  
	28.                             <div  id = 'proBar' class="bar" style="width: 0%"></div>  
	29.                         </div>  
	30.                     </div>  
	31.                 </div>  
	32.                   
	33.                  <div class="control-group">  
	34.                     <div class="controls">  
	35.                     <button type="button" id="subbut" class="btn">submit</button>  
	36.                     </div>  
	37.                 </div>  
	38.         </form>  
	39.         <iframe name="uploadf" style="display:none"></iframe>  
	40. </body>  
	41. </html>  
	42. <script >  
	43. $(document).ready(function(){  
	44.     $('#subbut').bind('click',  
	45.             function(){  
	46.                 $('#fForm').submit();  
	47.                 var eventFun = function(){  
	48.                     $.ajax({  
	49.                         type: 'GET',  
	50.                         url: '../process.json',  
	51.                         data: {},  
	52.                         dataType: 'json',  
	53.                         success : function(data){  
	54.                                 $('#proBar').css('width',data.rate+''+'%');  
	55.                                 $('#proBar').empty();  
	56.                                 $('#proBar').append(data.show);   
	57.                                 if(data.rate == 100){  
	58.                                     window.clearInterval(intId);  
	59.                                 }     
	60.                 }});};  
	61.                 var intId = window.setInterval(eventFun,500);  
	62.     });  
	63. });  
	64. </script> 

 

2.java 代码


import java.util.List;  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletResponse;  
import javax.servlet.http.HttpSession;  
import org.apache.commons.fileupload.FileItemFactory;  
import org.apache.commons.fileupload.ProgressListener;  
import org.apache.commons.fileupload.disk.DiskFileItemFactory;  
import org.apache.commons.fileupload.servlet.ServletFileUpload;  
import org.apache.log4j.Logger;  
import org.springframework.stereotype.Controller;  
import org.springframework.web.bind.annotation.RequestMapping;  
import org.springframework.web.bind.annotation.RequestMethod;  
import org.springframework.web.bind.annotation.ResponseBody;  
import org.springframework.web.servlet.ModelAndView;  
  
@Controller  
public class FileUploadController {  
    Logger log = Logger.getLogger(FileUploadController.class);  
      
    /** 
     * upload  上传文件 
     * @param request 
     * @param response 
     * @return 
     * @throws Exception 
     */  
    @RequestMapping(value = "/upload.html", method = RequestMethod.POST)  
    public ModelAndView upload(HttpServletRequest request,  
            HttpServletResponse response) throws Exception {  
        final HttpSession hs = request.getSession();  
        ModelAndView mv = new ModelAndView();  
        boolean isMultipart = ServletFileUpload.isMultipartContent(request);  
        if(!isMultipart){  
            return mv;  
        }  
        // Create a factory for disk-based file items  
        FileItemFactory factory = new DiskFileItemFactory();  
  
        // Create a new file upload handler  
        ServletFileUpload upload = new ServletFileUpload(factory);  
        upload.setProgressListener(new ProgressListener(){  
               public void update(long pBytesRead, long pContentLength, int pItems) {  
                   ProcessInfo pri = new ProcessInfo();  
                   pri.itemNum = pItems;  
                   pri.readSize = pBytesRead;  
                   pri.totalSize = pContentLength;  
                   pri.show = pBytesRead+"/"+pContentLength+" byte";  
                   pri.rate = Math.round(new Float(pBytesRead) / new Float(pContentLength)*100);  
                   hs.setAttribute("proInfo", pri);  
               }  
            });  
        List items = upload.parseRequest(request);  
        // Parse the request  
        // Process the uploaded items  
//      Iterator iter = items.iterator();  
//      while (iter.hasNext()) {  
//          FileItem item = (FileItem) iter.next();  
//          if (item.isFormField()) {  
//              String name = item.getFieldName();  
//              String value = item.getString();  
//              System.out.println("this is common feild!"+name+"="+value);  
//          } else {  
//              System.out.println("this is file feild!");  
//               String fieldName = item.getFieldName();  
//                  String fileName = item.getName();  
//                  String contentType = item.getContentType();  
//                  boolean isInMemory = item.isInMemory();  
//                  long sizeInBytes = item.getSize();  
//                  File uploadedFile = new File("c://"+fileName);  
//                  item.write(uploadedFile);  
//          }  
//      }  
        return mv;  
    }  
      
      
    /** 
     * process 获取进度 
     * @param request 
     * @param response 
     * @return 
     * @throws Exception 
     */  
    @RequestMapping(value = "/process.json", method = RequestMethod.GET)  
    @ResponseBody  
    public Object process(HttpServletRequest request,  
            HttpServletResponse response) throws Exception {  
        return ( ProcessInfo)request.getSession().getAttribute("proInfo");  
    }  
      
    class ProcessInfo{  
        public long totalSize = 1;  
        public long readSize = 0;  
        public String show = "";  
        public int itemNum = 0;  
        public int rate = 0;  
    }  
      
}  




但是,如果你的配置文件中有如下配置的话,以上方法就行不通了:


<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> 
    <property name="defaultEncoding" value="UTF-8" /> 
    <property name="maxUploadSize" value="2000000000" /> 
</bean>



因为这个配置会让你的SpringMVC中servletFileUpload解析为空!


解决办法就是重写CommonsMultipartResolver的parseRequest方法


1、首先将以上的bean注释掉,并加上下面的代码:


<bean id="multipartResolver" class=".../CommonsMultipartResolverExt">  //class为CommonsMultipartResolverExt类的路径
	<property name="defaultEncoding" value="UTF-8" />
	<property name="maxUploadSize" value="2000000000000" /> //上传文件大小限制
</bean>



2、重写CommonsMultipartResolver的parseRequest方法


import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import com.smax.ppd.util.FileUploadListener;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUpload;
import org.apache.commons.fileupload.FileUploadBase;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import org.springframework.web.multipart.MultipartException;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

public class CommonsMultipartResolverExt extends CommonsMultipartResolver {
    @Override
    protected MultipartParsingResult parseRequest(HttpServletRequest request)
            throws MultipartException {
        final HttpSession hs = request.getSession();
        FileUploadListener listener = new FileUploadListener(hs); //利用构造方法传递参数
        String encoding = determineEncoding(request);
        FileUpload fileUpload = prepareFileUpload(encoding);
        fileUpload.setProgressListener(listener);
        try {
            List<FileItem> fileItems = ((ServletFileUpload) fileUpload).parseRequest(request);
            return parseFileItems(fileItems, encoding);
        }
        catch (FileUploadBase.SizeLimitExceededException ex) {
            throw new MaxUploadSizeExceededException(fileUpload.getSizeMax(), ex);
        }
        catch (FileUploadException ex) {
            throw new MultipartException("Could not parse multipart servlet request", ex);
        }
    }
}

3、在上传的Controller代码中加上以下两行代码:


CommonsMultipartResolverExt commonsMultipartResolverExt = new CommonsMultipartResolverExt();
commonsMultipartResolverExt.parseRequest(request);

至此,就可以替代之前用bean配置所实现的功能


4、写一个监听类实现ProgressListener


import org.apache.commons.fileupload.ProgressListener;
import javax.servlet.http.HttpSession;

public class FileUploadListener implements ProgressListener {

    final HttpSession hs;

    public FileUploadListener(HttpSession hs) {
        this.hs = hs;
    }

    @Override
    public void update(long pBytesRead, long pContentLength, int pItems) {
        //pBytesRead 已经上传多少字节
        //pContentLength 一共多少字节
        //pItems 正在上传第几个文件
        ProcessInfo pri = new ProcessInfo();
        pri.itemNum = pItems;
        pri.readSize = pBytesRead;
        pri.totalSize = pContentLength;
        pri.show = Math.round(new Float(pBytesRead) / new Float(pContentLength)*100)+" %";
        pri.rate = Math.round(new Float(pBytesRead) / new Float(pContentLength)*100);
        hs.setAttribute("proInfo", pri);
    }

    public class ProcessInfo{
        public long totalSize = 1;
        public long readSize = 0;
        public String show = "";
        public int itemNum = 0;
        public int rate = 0;
    }

}


5、在Controller中写一个获取进度的方法


/**
 * process 获取进度
 * @param request
 * @param response
 * @return
 * @throws Exception
 */
@RequestMapping(value = "assetinfo/process", method = RequestMethod.GET)
@ResponseBody
public Map<String,Object> process(HttpServletRequest request,
							  HttpServletResponse response) throws Exception {

	Map<String,Object> map = new HashMap<>();


	FileUploadListener.ProcessInfo processInfo =  (FileUploadListener.ProcessInfo)request.getSession().getAttribute("proInfo");
	map.put("show", processInfo.show);
	map.put("rate", processInfo.rate);

	return map;
}



6、在前端页面按下上传按钮后用js进行处理,代码如下:


$('#saverecord').bind('click',
	function(){
		$('#addForm').submit(); //如果前端页面的按钮type为submit则此句可以不写
		var eventFun = function(){
			$.ajax({
				type: 'GET',
				url: 'assetinfo/process',
				data: {},
				dataType: 'json',
				success : function(data){
					$('#proBar').css('width',data.rate+''+'%');
					$('#proBar').empty();
					$('#proBar').append(data.show);
					if(data.rate == 100){
						window.clearInterval(intId); // 当文件上传为100%时终止
					}
				}});};
		var intId = window.setInterval(eventFun,1);//不停地调用eventFun方法与后端交互获取进度
	});

7、最后是前端jsp页面:


<label class="control-label">上传进度:</label>
<div class="controls">
	<div  class="progress progress-success progress-striped" style="width:100%">
		<div  id = 'proBar' class="bar" style="width: 0%"></div>
	</div>
</div>



至此,SpringMVC框架整合进度条就全部完成。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值