Flash vs J2EE -- FileUpload @ 邦邦的部落格 :: 隨意窩 Xuite日誌
  • 留言 & 文章索引
    1. 沒有新回應!
  • 流量統計
  • 2000年8月,
    加入e21摩奇創意,開始接觸 Flash 4。

    2004年3月,
    參與MMUG,分享與討論。

    2004年11月,
    通過 VUE 的 Flash MX 2004 Developer 認證。

    2005年6月,
    開始寫 Blog 分享自己所學。

    2005年7月,
    通過 MCI(Macromedia Certified Instractor) - Flash MX 2004 Developer 講師認證。

    2005年12月,
    終於於 DCI 拿到證書,正式成為第一屆也是最後一屆 Macromedia 的認證講師......$%&@#

    2006年8月,
    通過 ACI(Adobe Certified Instractor) - FlashLite 1.1 講師認證。

    2007年3月,
    離開待了六年半的摩奇創意,轉換跑道到BenQ。

    2007年5月,
    http://blog.ben.idv.tw

    2007年9月,
    BenQ品牌代工分家,我們變成新BenQ的母公司佳世達Qisda。

    2008年9月,
    因公司採用技術策略的轉變,故離開待了一年半的Qisda。

    2009年2月,
    加入一家低調的軟體公司,低調的開發著 Flash Game,呵呵~







  • 如何使用RSS
    Powered by Xuite
    2005-09-22 03:32 Flash vs J2EE -- FileUpload
    平均分數:0 顆星    投票人數:0
    我要評分:

    今晚,原本想來寫一個 Flash 8 的上傳程式,由 Java 接收檔案並儲存起來。結果在練習這個範例的過程中,遇到些問題尚未找出答案。

    Java 的程式碼如下:

    package idv.ben.file;
    
    import java.io.*;
    import java.util.*;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import org.apache.commons.fileupload.*;
    
    public class Upload extends javax.servlet.http.HttpServlet
    	implements javax.servlet.Servlet {
    	static final private long serialVersionUID = 1L;	 
    	
    	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		try {
    			System.out.println("==標頭==");
    			Enumeration enum = request.getHeaderNames();
    			while(enum.hasMoreElements()){
    				String header = (String)enum.nextElement();
    				System.out.println(header + " = " + request.getHeader(header));
    			}
    			
    			// Create a new file upload handler
    			DiskFileUpload upload = new DiskFileUpload();
    			
    			// Parse the request
    			List items = upload.parseRequest(request);
    			
    			// Process the uploaded items
    			Iterator iter = items.iterator();
    			while (iter.hasNext()) {
    			    FileItem item = (FileItem) iter.next();
    
    		    	String fieldName = item.getFieldName();
    		        String fileName = item.getName();
    		        String contentType = item.getContentType();
    		        boolean isInMemory = item.isInMemory();
    		        long sizeInBytes = item.getSize();
    
    		        System.out.println("==檔案==");
    		        System.out.println("fieldName = " + fieldName);
    		        System.out.println("fileName = " + fileName);
    		        System.out.println("contentType = " + contentType);
    		        System.out.println("isInMemory = " + isInMemory);
    		        System.out.println("sizeInBytes = " + sizeInBytes);
    			        
    		        String fileNameMain = fileName.lastIndexOf("")==-1?fileName:fileName.substring(fileName.lastIndexOf("")+1);
    		        System.out.println("fileNameMain = " + fileNameMain);
    				        
    		        File uploadDir = new File(this.getServletContext().getRealPath("/files"));
    		        if(!uploadDir.exists())uploadDir.mkdir();
    		        
    		        File uploadedFile = new File(this.getServletContext().getRealPath("/files/" + fileNameMain));
    		        item.write(uploadedFile);
    			}
    		} catch (FileUploadException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}   	  	    
    }

    我是利用 http://jakarta.apache.org/commons/fileupload/ 提供的 FileUpload 來作操作的,當收到上傳的檔案後,會將之儲存在名叫 files 的資料夾中。

    以下是 Flash 8 的程式碼:

    import flash.net.FileReference;
    var allTypes:Array = new Array();
    var imageTypes:Object = new Object();
    imageTypes.description = "Images (*.jpg, *.jpeg, *.gif, *.png)";
    imageTypes.extension = "*.jpg; *.jpeg; *.gif; *.png";
    allTypes.push(imageTypes);
    var listener:Object = new Object();
    listener.onSelect = function(file:FileReference):Void  {
    	trace("onSelect: "+file.name);
    	if (!file.upload("http://localhost/Flash_Upload/Upload")) {
    		trace("Upload dialog failed to open.");
    	}
    };
    listener.onCancel = function(file:FileReference):Void  {
    	trace("onCancel");
    };
    listener.onOpen = function(file:FileReference):Void  {
    	trace("onOpen: "+file.name);
    };
    listener.onProgress = function(file:FileReference, bytesLoaded:Number, bytesTotal:Number):Void  {
    	trace("onProgress with bytesLoaded: "+bytesLoaded+" bytesTotal: "+bytesTotal);
    };
    listener.onComplete = function(file:FileReference):Void  {
    	trace("onComplete: "+file.name);
    };
    listener.onHTTPError = function(file:FileReference):Void  {
    	trace("onHTTPError: "+file.name);
    };
    listener.onIOError = function(file:FileReference):Void  {
    	trace("onIOError: "+file.name);
    };
    listener.onSecurityError = function(file:FileReference, errorString:String):Void  {
    	trace("onSecurityError: "+file.name+" errorString: "+errorString);
    };
    var fileRef:FileReference = new FileReference();
    fileRef.addListener(listener);
    fileRef.browse(allTypes);
    

    其實在這其中,大部分都還是從 help 的範例程式碼中擷取出來使用的,當 Flash 一開始執行時,在 frame 1 就叫用 FileReference 的 browse() 來取得使用者電腦中的檔案,若是觸發 select 事件的話,就執行 upload() 上傳。

    執行之後,Flash 中 trace() 出來的訊息如下:

    onSelect: IMG_2940.JPG
    onOpen: IMG_2940.JPG
    onProgress with bytesLoaded: 32768 bytesTotal: 865102
    onProgress with bytesLoaded: 65536 bytesTotal: 865102
    onProgress with bytesLoaded: 131072 bytesTotal: 865102
    onProgress with bytesLoaded: 196608 bytesTotal: 865102
    onProgress with bytesLoaded: 229376 bytesTotal: 865102
    onProgress with bytesLoaded: 262144 bytesTotal: 865102
    onProgress with bytesLoaded: 294912 bytesTotal: 865102
    onProgress with bytesLoaded: 327680 bytesTotal: 865102
    onProgress with bytesLoaded: 458752 bytesTotal: 865102
    onProgress with bytesLoaded: 589824 bytesTotal: 865102
    onProgress with bytesLoaded: 655360 bytesTotal: 865102
    onProgress with bytesLoaded: 688128 bytesTotal: 865102
    onProgress with bytesLoaded: 720896 bytesTotal: 865102
    onProgress with bytesLoaded: 786432 bytesTotal: 865102
    onProgress with bytesLoaded: 851968 bytesTotal: 865102
    onProgress with bytesLoaded: 865102 bytesTotal: 865102
    onComplete: IMG_2940.JPG
    

    Java 這邊背後輸出的訊息卻是:

    ==標頭==
    accept = text/*
    content-type = multipart/form-data; boundary=----------gL6cH2ae0ei4KM7Ef1gL6Ef1gL6GI3
    user-agent = Shockwave Flash
    host = localhost
    content-length = 0
    connection = Keep-Alive
    cache-control = no-cache
    ==標頭==
    accept = text/*
    content-type = multipart/form-data; boundary=----------gL6cH2ae0ei4KM7Ef1gL6Ef1gL6GI3
    user-agent = Shockwave Flash
    host = localhost
    content-length = 865520
    connection = Keep-Alive
    cache-control = no-cache
    org.apache.commons.fileupload.FileUploadException: Processing of multipart/form-data request failed. Stream ended unexpectedly
    	at org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:429)
    	at idv.ben.file.Upload.doPost(Upload.java:27)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
    	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
    	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
    	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
    	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
    	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
    	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
    	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
    	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
    	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:856)
    	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:744)
    	at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
    	at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80)
    	at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
    	at java.lang.Thread.run(Thread.java:595)
    

    為了單純測試這個上傳 Java 是否有問題,所以我另外做了一個 test.html 來讓事情單純一點,果然就可以正常上傳成功了,Java 輸出的訊息為:

    ==標頭==
    accept = */*
    referer = http://localhost/Flash_Upload/test.html
    accept-language = zh-tw
    content-type = multipart/form-data; boundary=---------------------------7d5731c8019a
    accept-encoding = gzip, deflate
    user-agent = Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)
    host = localhost
    content-length = 865371
    connection = Keep-Alive
    cache-control = no-cache
    ==檔案==
    fieldName = file
    fileName = C:Documents and SettingsBenMy DocumentsMy Pictures20050917_摩奇晚餐photosIMG_2940.JPG
    contentType = image/pjpeg
    isInMemory = false
    sizeInBytes = 865102
    fileNameMain = IMG_2940.JPG
    

    由上面的比對當中,由錯誤訊息 org.apache.commons.fileupload.FileUploadException: Processing of multipart/form-data request failed. Stream ended unexpectedly at idv.ben.file.Upload.doPost(Upload.java:27) 來看,我一開始猜測會不會是因為 Flash 對外傳遞資料時的封包結尾字元有什麼特別之處。後來看到 html 與 Flash 的兩個測試比對後,感覺上又沒有什麼關鍵的大不同之處。只是,有點詭異的是,發生錯誤時,header 標頭的部份被印出兩次,而且其中的第一次還有 content-length = 0 這個項目,第二次卻為 content-length = 865520。這些資訊讓我還有點摸不著頭緒。

    我用來測試的 Flash 版本,還是先前的測試版軟體,所以我也不敢保證是否是測試版的問題,但是以前也有人可以寫出正常的效果,所以我也在想會不會是我以 Java 實做時,少考慮了什麼部份。原本以為只要 html 版的上傳能正常執行,應該前端就只是由 html 換成 Flash 而已,後端應該不用有任何改變才對,不過,現在看來,一定還有什麼遺漏之處。

    邦邦 / Xuite日誌 / 回應(10) / 引用(0) / 好文轉寄
    回應