Servlet學習三——傳輸文件

     最早在考慮傳輸文件時,想經過java寫一個文件上傳案例,傳給Servlet,Servlet再保存至數據庫中,但苦於一直沒找到實例,據說Flex有實際的例子,就直接用Flex例子來測試了。本文的順序爲:Flex測試代碼,數據庫接收代碼,Sql與Oracle數據庫處理的區別。html

      1.Flex中文件上傳的範例代碼:java

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
			   xmlns:s="library://ns.adobe.com/flex/spark" 
			   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
	<fx:Script>
		<![CDATA[
			import mx.controls.Alert;
			
			private var imageFR:FileReference = new FileReference();
			
			protected function loadstaphotoB_clickHandler(event:MouseEvent):void
			{
				//
				var ff:FileFilter = new FileFilter("圖片文件 (*.jpg, *.aac)","*.jpg; *.aac;");
				imageFR.addEventListener(Event.SELECT, selectimageHandler);
				imageFR.browse([ff]);
			}
			
			private function selectimageHandler(event:Event):void {
				//增長一個文件加載load完成後的listener	
				imageFR.addEventListener(Event.COMPLETE, onLoadimageComplete);
				imageFR.load(); //加載用戶選中文件
			}
			
			private function onLoadimageComplete(event:Event):void
			{			
//				var request:URLRequest = new URLRequest("http://localhost:8400/DataDemoServer/StaImageSave");
				var request:URLRequest = new URLRequest("http://192.168.169.26:8080/bb/TestFlexServlet");
//				var request:URLRequest = new URLRequest("http://192.168.169.26:8080/SSCTaxi/SendOrderServlet");
				request.method = URLRequestMethod.POST;
				imageFR.addEventListener(Event.COMPLETE,imageUploadComplete);
				imageFR.addEventListener(IOErrorEvent.IO_ERROR,uploadError);
				
				imageFR.upload(request,imageFR.name);
			}
			
			private function imageUploadComplete(event:Event):void
			{				
				Alert.show("上傳圖片成功!", "抱歉", 4, this);
			}
			
			private function uploadError(event:IOErrorEvent):void
			{
				Alert.show("上傳圖片失敗!", "抱歉", 4, this);
			}
		]]>
	</fx:Script>
	<s:layout>
		<s:BasicLayout/>
	</s:layout>
	<fx:Declarations>
		<!-- 將非可視元素(例如服務、值對象)放在此處 -->
	</fx:Declarations>
	<s:Button label="上傳" click="loadstaphotoB_clickHandler(event)"/>
</s:Application>

     有了上傳文件的測試代碼,就能夠開始着手寫接收流的代碼了。數據庫

     2.接收流的代碼:網絡

ServletInputStream stream;
		try {
			stream = request.getInputStream();
			int streamLength = request.getContentLength();
			PassengerDAO dao = new PassengerDAO();
			String result = dao.insertMsg(stream, streamLength);

			try {
				PrintWriter out = response.getWriter();
				out.println(result);
				out.flush();
				out.close();

			} catch (Exception e) {
				e.printStackTrace();
			}
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

  在完成接收流代碼過程當中,走了很多彎路,主要體如今兩方面:InputStream和流長度獲取。 測試

      1).InputStream:最初寫流的獲取時,因想經過Java本身寫一個上傳的,找了很多資料,主要使用【commons-fileupload-1.3】這個包,最初本身也用了這個包,使用這個包來獲取流,DiskFileItemFactory——ServletFileUpload——FileItem等等,各個步驟,步驟很繁瑣,但最後也獲得了InputStream。直到最後數據庫須要從Oracle換到SQL時,本身才意識到能夠直接從Request.getInputStream直接獲取輸入流,這個時候真的是感嘆本身捨本逐末。flex

      2).流長度獲取:在Oracle中使用Blob字段,能夠經過Blob.getBinaryOutputStream方法獲取輸出流後,使用InputStream往輸出流中寫數據,但數據庫換成SQL後,使用了SQL中Image字段,這時往數據庫中寫入流是經過setBinaryStream,這個方法須要傳入流的大小,但流的大小是無從所知的。查了不少知道,都說available方法在網絡傳輸是不穩定的,在網絡傳輸中獲取大小爲0,測試了一把,果真是零,難道我須要將流先存成文件,再獲取文件大小?相信網絡獲取流確定有其餘人實現過,繼續找,後來在一篇網文中看到了Request.getContentLength,再次感覺到了根基差帶來的劣勢,不少東西都須要積澱,沒有過硬的能力不要想一蹴而就。this

     3.Sql與Oracle存儲區別spa

     1)時間字段xml

     Oracle裏使用的是Timestamp,很方便,但在獲取前須要設置鏈接的時區,相似【((OracleConnection) conn).setSessionTimeZone("GMT");】,在SQL中使用的是smalldatetime,不須要設置時區,能設置默認值爲當前時間,估計Oracle也有,但本身沒有去摸索;htm

     2)大字段

     大字段的區別在前面已經提了,Blob不須要提早了解InputStream的長度,但Image字段須要。

相關文章
相關標籤/搜索