Fortschrittsanzeige beim Upload mit AJAX XML JAVA Servlet

uwe75-1

Mitglied
Hallo,

ich versuchenun schon seit Wochen eine Fortschrittsanzeige für den Dateiupload hinzubekommen.
Dazu habe eine ganz normale HTML Seite mit einem Formularfeld, in dem die Datei angegeben werden muß. Diese wird an den POST-Teil eines Servlets geschickt und dabei eine Session im Servlet eröffnet und ein Listener aktiviert. Gleichzeitig wird beim Absenden des Formulars mit "onsubmit" eine Javascript Funktion aufgerufen. Diese sendet in regelmäßen Abständen requests an den GET Teil des Servlets. Meine Probleme sind nun folgende:
1.) Die Session-ID im GET und POST Teil unterscheiden sich, dadurch kann gibt der Listener im GET Teil auch einen falschen Wert aus.
2.) Erst nach dem der Upload beendet ist, sind die Session-ID identisch und dann gibt auch der Listener den korrekten Wert aus, aber das ist halt a bisl spät;-)
3.) Bei Test im IE erfolgt die Javascript-Anfrage an den GET Teil des Servlets nur einmal, während die Anfrage im Firefox schon regelmäßig gemacht wird - Woran liegt das?

Hiermal die entscheidenden Quell-Code-Ausschnitte:
Code:
<script language="javascript">
// var counter = 0;
var req;
function ajaxFunction() {
	var url = "FileUploadServlet"; //?random="+rnd;
	if (typeof XMLHttpRequest != 'undefined') {
		req = new XMLHttpRequest();
	}
	if (req) {
		req.open('GET', url, true);
		req.onreadystatechange = processStateChange;
		req.setRequestHeader("Pragma", "no-cache");
		req.setRequestHeader("Cache-Control", "must-revalidate");
		req.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT");
		req.send(null);
	}
}

function processStateChange() {
	
	if (req.readyState == 4) {
			if (req.status == 200) {  //OK response
			var xml = req.responseXML;
			var isNotFinished = xml.getElementsByTagName("finished")[0];
			var myBytesRead = xml.getElementsByTagName("bytes_read")[0];
			var myContentLength = xml.getElementsByTagName("content_length")[0];
			var myPercent = xml.getElementsByTagName("percent_complete")[0];
			if ((isNotFinished == null) && (myPercent == null)) {
				document.getElementById("initializing").style.visibility = "visible";
				window.setTimeout("ajaxFunction()",5000);
			}
			else {
				document.getElementById("initializing").style.visibility = "hidden";
				document.getElementById("progressBarTable").style.visibility = "visible";
				document.getElementById("percentCompleteTable").style.visibility = "visible";
				document.getElementById("bytesRead").style.visibility = "visible";
				myBytesRead = myBytesRead.firstChild.data;
				myContentLength = myContentLength.firstChild.data;
				if (myPercent != null) {
					myPercent = myPercent.firstChild.data;
					document.getElementById("progressBar").style.width = percent + "%";
					document.getElementById("bytesRead").innerHTML = myBytesRead + " of " + myContentLength + " bytes read";
					document.getElementById("percentComplete").innerHTML = myPercent + "%";
					window.setTimeout("ajaxFunction()", 5000);
				}
				else {
					document.getElementById("bytesRead").style.visibility = "hidden";
					document.getElementById("progressBar").style.width = "100%";
					document.getElementById("percentComplete").innerHTML = "Done!";
				}
			}
		}
		else {
			alert(req.statusText);
		}
	}
}


</script>

Und nu das Servlet:

public class FileUploadServlet extends HttpServlet implements Servlet
 {
   private static final long serialVersionUID = 2740693677625051632L;
   String fileName, filePath;
   
    /* (non-Java-doc)
	 * @see javax.servlet.http.HttpServlet#HttpServlet()
	 */
	public FileUploadServlet() {
		super();
	}   	
	
	/* (non-Java-doc)
	 * @see javax.servlet.http.HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
   
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		PrintWriter out = response.getWriter();
	    PrintWriter stdout = new PrintWriter(System.out,true);
		HttpSession session = request.getSession();
		ProgressListenerImpl listener = null;
		StringBuffer buffy = new StringBuffer();
		long bytesRead = 0;
		long contentLength = 0;
		long percent = 0;
		stdout.println("Session get: "+session);
		if (session == null) {
			return;
		}
		else if (session != null) {
			listener = (ProgressListenerImpl) session.getAttribute("Listener");
			stdout.println("listener: "+listener);
			if (listener == null) {
				return;
			}
			else {
				percent = listener.getPercentComplete();
				stdout.println("percent: "+percent);
			}
		}
		response.setContentType("text/xml");
		buffy.append("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n");
		buffy.append("<response>\n");
		buffy.append("\t<bytes_read>"+bytesRead+"</bytes_read>\n");
		buffy.append("\t<content_length>" + contentLength + "</content_length>\n");
		if (bytesRead == contentLength) {
			buffy.append("\t<finished />\n");
			session.setAttribute("Listener",null);
		}
		else {
			long percentComplete = ((100 * bytesRead) / contentLength);
			buffy.append("\t<percent_complete>" + percentComplete + "</percent_complete>\n");
		}
		buffy.append("</response>\n");
		out.println(buffy.toString());
		out.flush();
		out.close();
	}  	
	
	/* (non-Java-doc)
	 * @see javax.servlet.http.HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
   
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		PrintWriter stdout = new PrintWriter(System.out,true);
		FileItemFactory factory = new DiskFileItemFactory();
		ServletFileUpload upload = new ServletFileUpload(factory);
		ProgressListenerImpl listener = new ProgressListenerImpl();
		HttpSession session = request.getSession();
		session.setAttribute("Listener",listener);
		stdout.println("session post: "+session);
		upload.setProgressListener(listener);
		List uploadedItems = null;
		FileItem fileItem = null;
		filePath = getServletContext().getRealPath("/")+"temp_dir\\"+password+"\\";
	    	if (!new File(filePath).isDirectory()) new File(filePath).mkdirs();
                    
                         Jetzt folgt nur noch die Upload-Routine

Vielen Dank schon mal für Eure Hilfe im Voraus - bin echt am verzweifeln!

Uwe
 
Hi Uwe,

wenn die SessionIDs auseinanderlaufen kann das nicht funktionieren.

Wenn Du Cookies verwendest, sollte der AJAX Request die SessionID automatisch mitschicken.
Falls die SessionID bei Dir in der URL übergeben wird, müsstest Du die auch beim AJAX Aufruf mitgeben.

Gruß
joschi
 
Zuletzt bearbeitet:
Hallo Joschi,

vielen Dank für dein Tip - kann zwar momentan damit nicht viel anfangen, aber ich werde mich in Foren mal weiter schlau machen über Session_ID's.
Zwischenzeitlich ist folgendes Phänomen aufgetreten:
Wenn ich ein neues Browsserfenster starte funktioniert mein Programm nach dem ersten Start nicht - aber ab einem zweiten Start laufen keine Sessions mehr auseinander, dann funktioniert das einwandfrei. Jetzt muß ich mal rauskriegen, woran das liegen könnte.

Gruß Uwe
 
Hallo,

das mit den Session-ID'S habe ich hinbekommen, nu habe ich aber schon wieder ein neues Problem:

Die Anzeige wird mit dem Ajax Request alle 0.5 s aktualisiert
Der Upload kleiner Dateien funktioniert einwandfrei, aber bei Dateien mit z.B. 160 MB unterbricht die Fortschrittsanzeige einmal für 2-3 Minuten und dann läuft Sie normal weiter. Das passiert immer bei den ersten 10% des Fortschritts und dann nie wieder. Ich habe jetzt schon einen Timer eingebaut, so daß wenn der Respnse zu lange dauert, daß dann der Request abgebrochen wird und neu initialisiert wird. Kurz vor dem Abbruch ist der ReadyState-Wert 1, d.h. doch, daß die Anfrage an den Server gar nicht gesendet wurde, oder?

Woran kann das liegen?

Vielen Dank schon mal für Eure Hilfe, falls Ihr Rat wißt

Gruß Uwe
 

Neue Beiträge

Zurück