Using jsp + extjs to realize dynamic display of file upload progress

Time:2020-11-25

The demand source is as follows: upload a large excel file to the server. The server will parse the excel file and insert it into the database one by one. The whole process takes a long time. Therefore, after the user clicks upload, a progress bar needs to be displayed, and the progress bar can be updated timely according to the amount of data received and the progress of processing in the background.

analysis:Two components are required in the background, uploadController.jsp It is used to receive and process data. It will dynamically put the progress information into the session, another component processController.jsp Used to update the progress bar; after the user clicks “Upload”, the form is submitted to the uploadController.jsp At the same time, start an Ajax request to the processController.jsp , AJAX uses the percentage of progress obtained Update the progress bar to show the progress, and the process is repeated every second; this is the basic principle of this example.

Now the problem is how to know how much data the server receives accounts for the total data when receiving data? If we write a file upload component from scratch, this problem can be solved very well. The key is that we often use mature components, such as Apache Commons fileUpload. Fortunately, Apache has thought of this problem for a long time, so it has reserved an interface to obtain the percentage of received data. Therefore, I use Apache Commons File upload to receive the uploaded file.

uploadController.jsp:

<%@ page language="java" import="java.util.*, java.io.*, org.apache.commons.fileupload.*, org.apache.commons.fileupload.disk.DiskFileItemFactory, org.apache.commons.fileupload.servlet.ServletFileUpload" pageEncoding="utf-8"%>
<%
//Note that the import jar package above is required
//The following is the use of Apache Commons fileUpload to receive uploaded files;
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
//Since the inner class cannot refer to request, we need to implement one.
class MyProgressListener implements ProgressListener{
	private HttpServletRequest request = null;
	MyProgressListener(HttpServletRequest request){
		this.request = request;
	}
	public void update(long pBytesRead, long pContentLength, int pItems) {
		double percentage = ((double)pBytesRead/(double)pContentLength);
		//The upload progress is saved to the session so that processController.jsp use
		request.getSession().setAttribute("uploadPercentage", percentage);
	}
}
upload.setProgressListener(new MyProgressListener(request));
List items = upload.parseRequest(request);
Iterator iter = items.iterator();
while (iter.hasNext()) {
  FileItem item = (FileItem) iter.next();
  if (item.isFormField()){
  	
  } else {
    //String fieldName = item.getFieldName();
    String fileName = item.getName();
    //String contentType = item.getContentType();
    System.out.println();
    boolean isInMemory = item.isInMemory();
    long sizeInBytes = item.getSize();
    File uploadedFile = new File("c://" + System.currentTimeMillis() + fileName.substring(fileName.lastIndexOf(".")));
    item.write(uploadedFile);
  }
}
out.write ({ success:true , MSG: 'save the uploaded file data and analyze excel successfully!'} ');
out.flush();
%>

processController.jsp:

<%@ page language="java" import="java.util.*" contentType = "text/html;charset=UTF-8" pageEncoding="utf-8"%>
<%
	//It is necessary to pay attention to the head above. Otherwise, there will be Ajax garbled problems.
	//Take uploadpercentage from session and send it back to browser
	Object percent = request.getSession().getAttribute("uploadPercentage");
	String msg = "";
	double d = 0;
	if(percent==null){
		d = 0;
	}
	else{
		d = (Double)percent;
		//System.out.println("+++++++processController: " + d);
	}
	if(d<1){
	//D < 1 means uploading,
		MSG: "uploading file...";
		out.write("{success:true, msg: '"+msg+"', percentage:'" + d + "', finished: false}");
	}
	else if(d>=1){
		//d> 1 means that the upload is finished, and the analysis of Excel is started,
		//This example only simulates the processing of Excel, and places a processexcelpercentage in the session to represent the progress of analyzing excel.
		MSG: "analyzing and processing excel...";
		String finished = "false";
		double processExcelPercentage = 0.0;
		Object o = request.getSession().getAttribute("processExcelPercentage");
		if(o==null){
			processExcelPercentage = 0.0;
			request.getSession().setAttribute("processExcelPercentage", 0.0);
			
		}
		else{
			//Excel was simulated and the percentage was increased by 0.1 each time 
			processExcelPercentage = (Double)o + 0.1;
			request.getSession().setAttribute("processExcelPercentage", processExcelPercentage);
			if(processExcelPercentage>=1){
				//When processexcelpercentage > 1, excel analysis is completed.
				request.getSession().removeAttribute("uploadPercentage");
				request.getSession().removeAttribute("processExcelPercentage");
				//Flag for the client to judge whether to end or not
				finished = "true";
			}
		}
		out.write("{success:true, msg: '"+msg+"', percentage:'" + processExcelPercentage + "', finished: "+ finished +"}");
		//Note that the returned data, success represents the state
		//Percentage is the percentage
		//Finished represents whether the whole process is over.
	}
	out.flush();
%>

Form page upload.html :

<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
		<title>File Upload Field Example</title>
		<link rel="stylesheet" type="text/css"
			href="ext/resources/css/ext-all.css" />
		<script type="text/javascript" src="ext/adapter/ext/ext-base.js"> </script>
		<script type="text/javascript" src="ext/ext-all.js"> </script>
		<style>
</style>
	</head>
	<body>
		<a href="http://blog.csdn.net/sunxing007">sunxing007</a>
		<div></div>
	</body>
	<script>
var fm = new Ext.FormPanel({
	Title: 'upload excel file',
	url:'uploadController.jsp?t=' + new Date(),
	autoScroll:true,
	applyTo: 'form',
	height: 120,
	width: 500,
	frame:false,
	fileUpload: true,
	defaultType:'textfield',
	labelWidth:200,
	items:[{
		xtype:'field',
		Fieldlabel: 'please select the excel file to upload',
		allowBlank:false,
		inputType:'file',
		name:'file'
	}],
	buttons: [{
		Text: 'start uploading',
		handler: function(){
			//After clicking 'start upload', it will be handled by this function.
		  If ( fm.form.isValid ()) {// verify the form, which is omitted in this example
		  //Show progress bar
				Ext.MessageBox.show({ 
				  Title: 'uploading file', 
				  //msg: 'Processing...', 
				  width:240, 
				  progress:true, 
				  closable:false, 
				  buttons:{cancel:'Cancel'} 
				}); 
				//Form submission
    fm.getForm().submit();
    //Set a timer to send Ajax requests to processcontroller every 500 ms
		  var i = 0;
		  var timer = setInterval(function(){
		  		//Request case
			   Ext.Ajax.request({
			   //The writing method of the following URL is very important. I have been debugging for this for a long time
			   //In the future, the URL of the Ajax request should be marked with a date stamp,
			   //Otherwise, it is very likely that the data will be the same every time,
			   //This has to do with browser caching
						url: 'processController.jsp?t=' + new Date(),
						method: 'get',
						//Processing the return data of Ajax
						success: function(response, options){
							status = response.responseText + " " + i++;
							var obj = Ext.util.JSON.decode(response.responseText);
							if(obj.success!=false){
								if(obj.finished){
									clearInterval(timer);	
									//status = response.responseText;
									Ext.MessageBox.updateProgress(1, 'finished', 'finished');
									Ext.MessageBox.hide();
								}
								else{
									Ext.MessageBox.updateProgress(obj.percentage, obj.msg);	
								}
							}
						},
						failure: function(){
							clearInterval(timer);
							Ext.Msg.alert ('error ','An error has occurred. ).
						} 
					});
		  }, 500);
		    
		  }
		  else{
		  	Ext.Msg.alert "Message", "please select excel file before uploading.");
		  }
		} 
	}]
});
</script>
</html>

Put these three files in Tomcat / webapps / root /, and put the main file of ext here. Start Tomcat to test: http://localhost :8080/ upload.html

There are complete sample files in my resources:Click to downloadAfter downloading the zip file, unzip it to Tomcat / webapps / root / to test.

Finally, we need to remind you that because the fileUpload component of Apache is used, we need to put the common- fileupload.jar Put it under root / WEB-INF / lib.