隨筆 - 312, 文章 - 14, 評論 - 1393, 引用 - 0

          導航

          <2009年3月>
          22232425262728
          1234567
          891011121314
          15161718192021
          22232425262728
          2930311234

          公告

          關注我的新浪微博

          我的著作









          常用鏈接

          留言簿(126)

          我參與的團隊

          隨筆分類(818)

          隨筆檔案(310)

          文章分類(1)

          文章檔案(8)

          相冊

          ADSL、3G查詢

          CSDN

          eclipse

          ibm

          Java EE

          Linux

          Web

          云服務

          代理網站

          關注的網站

          協議

          喜歡的Blog

          國內廣告平臺

          圖書出版

          在線培訓

          開發工具

          微博客戶端

          手機鈴聲

          操作系統

          • ReactOS
          • 一個與windowXP/2003兼容的操作系統

          數學

          文件格式

          源碼資源

          移動(Mobile)

          編程語言

          英語學習

          最新隨筆

          搜索

          •  

          積分與排名

          • 積分 - 1973555
          • 排名 - 6

          最新評論

          閱讀排行榜

          評論排行榜

          WebService大講堂之Axis2(4):二進制文件傳輸

          本文為原創,如需轉載,請注明作者和出處,謝謝!

          上一篇:
          WebService大講堂之Axis2(3):使用services.xml文件發布WebService 

              在《WebService大講堂之Axis2(2):復合類型數據的傳遞》中講過,如果要傳遞二進制文件(如圖像、音頻文件等),可以使用byte[]作為數據類型進行傳遞,然后客戶端使用RPC方式進行調用。這樣做只是其中的一種方法,除此之外,在客戶端還可以使用wsdl2java命令生成相應的stub類來調用WebServicewsdl2java命令的用法詳見《WebService大講堂之Axis2(1):用POJO實現0配置的WebService》。
              WebService類中包含byte[]類型參數的方法在wsdl2java生成的stub類中對應的數據類型不再是byte[]類型,而是javax.activation.DataHandlerDataHandler類是專門用來映射WebService二進制類型的。
              在
          WebService類中除了可以使用byte[]作為傳輸二進制的數據類型外,也可以使用javax.activation.DataHandler作為數據類型。 不管是使用byte[],還是使用javax.activation.DataHandler作為WebService方法的數據類型,使用wsdl2java命令生成的stub類中相應方法的類型都是javax.activation.DataHandler。而象使用.netdelphi生成的stub類的相應方法類型都是byte[]。這是由于javax.activation.DataHandler類是Java特有的,對于其他語言和技術來說,并不認識javax.activation.DataHandler類,因此,也只有使用最原始的byte[]了。
              下面是一個上傳二進制文件的例子,
          WebService類的代碼如下:

          package service;

          import java.io.InputStream;
          import java.io.OutputStream;
          import java.io.FileOutputStream;
          import javax.activation.DataHandler;

          public class FileService
          {
             
          //  使用byte[]類型參數上傳二進制文件
              public boolean uploadWithByte(byte[] file, String filename)
              {
                   FileOutputStream fos 
          = null;
                   
          try
                   {                          
                       fos 
          = new FileOutputStream(filename);    
                       fos.write(file);
                       fos.close();
                   }
                   
          catch (Exception e)
                   {
                       
          return false;
                   }
                   
          finally
                   {
                       
          if (fos != null)
                       {
                           
          try
                           {
                               fos.close();
                           }
                           
          catch (Exception e)
                           {
                           }
                       }
                   }
                   
          return true;
              }
              
          private void writeInputStreamToFile(InputStream is, OutputStream os) throws Exception
              {
                   
          int n = 0;
                   
          byte[] buffer = new byte[8192];
                   
          while((n = is.read(buffer)) > 0)
                   {
                       os.write(buffer, 
          0, n);
                   }
              }
              
          //  使用DataHandler類型參數上傳文件
              public boolean uploadWithDataHandler(DataHandler file, String filename)
              {
                  
                   FileOutputStream fos 
          = null;
                   
          try
                   {            
                       fos 
          = new FileOutputStream(filename);   
                       
          //  可通過DataHandler類的getInputStream方法讀取上傳數據
                       writeInputStreamToFile(file.getInputStream(), fos);
                       fos.close();
                   }
                   
          catch (Exception e)
                   {
                       
          return false;
                   }
                   
          finally
                   {
                       
          if (fos != null)
                       {
                           
          try
                           {
                               fos.close();
                           }
                           
          catch (Exception e)
                           {
                           }
                       }
                   }
                   
          return true;
              }
          }

          上面代碼在services.xml文件的配置代碼如下:

          <service name="fileService">
              
          <description>
                  文件服務
              
          </description>
              
          <parameter name="ServiceClass">
                  service.FileService 
              
          </parameter>
                  
          <messageReceivers>
                  
          <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
                      class
          ="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
              
          </messageReceivers>
          </service>


              如果使用
          wsdl2java命令生成調用Java客戶端代碼,則需要創建DataHandler類的對象實例,代碼如下:

          DataHandler dh = new DataHandler(new FileDataSource(imagePath));

          wsdl2java命令會為每一個方法生成一個封裝方法參數的類,類名為方法名(第一個字符大寫),如uploadWithByte方法生成的類名為UploadWithByte。如果要設置file參數的值,可以使用UploadWithByte類的setFile方法,代碼如下:


          UploadWithByte uwb = new UPloadWithByte();
          uwb.setFile(dh);

          最后是調用uploadWithByte方法,代碼如下(FileServiceStubwsdl2java生成的stub類名):


          FileServiceStub fss = new FileServiceStub();
          fss.uploadWithByte(uwb);

          如果使用C#調用FileService,則file參數類型均為byte[],代碼如下:

          MemoryStream ms = new MemoryStream();
          Bitmap bitmap 
          = new Bitmap(picUpdateImage.Image);
          bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
          service.fileService fs 
          = new WSC.service.fileService();
          fs.uploadWithDataHandler(ms.ToArray());
          fs.uploadWithByte(ms.ToArray());
           

          其中picUpdateImagec#中加載圖像文件的picturebox控件。

          下一篇:
          WebService大講堂之Axis2(5):會話(Session)管理





          Android開發完全講義(第2版)(本書版權已輸出到臺灣)

          http://product.dangdang.com/product.aspx?product_id=22741502



          Android高薪之路:Android程序員面試寶典 http://book.360buy.com/10970314.html


          新浪微博:http://t.sina.com.cn/androidguy   昵稱:李寧_Lining

          posted on 2009-01-22 10:28 銀河使者 閱讀(22563) 評論(18)  編輯  收藏 所屬分類: java 原創webservice

          評論

          # re: WebService大講堂之Axis2(4):二進制文件傳輸  回復  更多評論   

          贊!
          2009-01-23 22:25 | zuzong

          # re: WebService大講堂之Axis2(4):二進制文件傳輸  回復  更多評論   

          支持!
          2009-02-01 13:53 | BeanSoft

          # re: WebService大講堂之Axis2(4):二進制文件傳輸  回復  更多評論   

          太好了!!支持!
          2009-02-16 22:39 | 宋丙坤

          # re: WebService大講堂之Axis2(4):二進制文件傳輸  回復  更多評論   

          sql查詢的結果ResultSet,如何進行傳輸啊?
          2009-03-30 14:20 | passerby

          # re: WebService大講堂之Axis2(4):二進制文件傳輸  回復  更多評論   

          @passerby
          webservice不支持ResultSet類型,一般將ResultSet中的數據放到對象數組中。如果你用hibernate這樣的ORM就方便的多,這也是ORM的重要應用之一。
          2009-03-30 14:26 | 銀河使者

          # re: WebService大講堂之Axis2(4):二進制文件傳輸  回復  更多評論   

          怎么沒寫客戶端代碼啊!
          2009-05-18 09:30 |

          # re: WebService大講堂之Axis2(4):二進制文件傳輸  回復  更多評論   

          后面有客戶端代碼
          2009-05-18 12:44 | 銀河使者

          # re: WebService大講堂之Axis2(4):二進制文件傳輸  回復  更多評論   

          支持作者,不錯不錯,謝謝,很好啊。
          2009-05-18 18:13 | Harold.Zhang

          # re: WebService大講堂之Axis2(4):二進制文件傳輸  回復  更多評論   

          怎么沒寫客戶端代碼啊!
          2009-10-19 16:48 | cjoy

          # re: WebService大講堂之Axis2(4):二進制文件傳輸  回復  更多評論   

          多謝作者辛勤勞動~~
          能不能寫一個 axis2、MySQL、web技術 結合的例子呀?
          2009-10-23 20:17 | lce

          # re: WebService大講堂之Axis2(4):二進制文件傳輸  回復  更多評論   

          好文章,謝謝了,請問下我做了個從別人服務器下載文件,以byte[]進行傳輸,為什么文件超過10M就報內存溢出呢?
          2009-10-31 08:53 | zsy

          # re: WebService大講堂之Axis2(4):二進制文件傳輸  回復  更多評論   

          當然會報錯,是因為超過了java允許的數組長度,下載大文件最好直接用http,不用webservice。webservice是用來傳數據的,不是用來下文件的。
          2009-10-31 20:57 | 銀河使者

          # re: WebService大講堂之Axis2(4):二進制文件傳輸 2009-03-30 14:26 銀河使者   回復  更多評論   

          @銀河使者
          建議客戶端代碼我想作者還是不要給出的好。首先,客戶端代碼的兩種書寫方式作者在上文都有介紹,而且無論是用wsdl2java命令生成客戶端代碼還是直接用RPC方式書寫客戶端代碼,都需要我們在自己的機器上親自動手操作一遍才能印象深刻,在這個過程中,幾乎都會報出各種各樣的錯誤,那么解決這一個個的錯誤是不是就是給讀者一個很好的學習過程呢?
          2009-11-02 17:33 | Mr.Blue

          # re: WebService大講堂之Axis2(4):二進制文件傳輸  回復  更多評論   

          我自己做了個客戶端
          RPCServiceClient serviceClient = new RPCServiceClient();
          Options options = serviceClient.getOptions();
          EndpointReference targetEPR = new EndpointReference("http://localhost:8080/axis2/services/fileService");
          options.setTo(targetEPR);
          // 下面的代碼調用uploadImageWithByte方法上傳圖像文件
          /////////////////////////////////////////
          // 打開圖像文件,確定圖像文件的大小
          java.io.File file = new java.io.File("f:\\images.jpg");
          java.io.FileInputStream fis = new java.io.FileInputStream("f:\\31.txt");
          // 創建保存要上傳的圖像文件內容的字節數組
          byte[] buffer = new byte[(int) file.length()];
          // 將圖像文件的內容讀取buffer數組中
          int n = fis.read(buffer);
          System.out.println("文件長度:" + file.length());
          Object[] opAddEntryArgs = new Object[]{ buffer,"d:\\31.txt" };
          Class[] classes = new Class[]{ Boolean.class };
          QName opAddEntry = new QName("http://ws.apache.org/axis2","uploadWithByte"" target="_new" rel="nofollow">http://ws.apache.org/axis2","uploadWithByte");
          fis.close();
          // 開始上傳圖像文件,并輸出uploadWithByte方法的返回傳
          System.out.println(serviceClient.invokeBlocking(opAddEntry,opAddEntryArgs, classes)[0]);
          但是報錯:
          Exception in thread "main" org.apache.axis2.AxisFault: namespace mismatch require http://service found http://ws.apache.org/axis2
          at org.apache.axis2.util.Utils.getInboundFaultFromMessageContext(Utils.java:512)
          at org.apache.axis2.description.OutInAxisOperationClient.handleResponse(OutInAxisOperation.java:370)
          at org.apache.axis2.description.OutInAxisOperationClient.send(OutInAxisOperation.java:416)
          at org.apache.axis2.description.OutInAxisOperationClient.executeImpl(OutInAxisOperation.java:228)
          at org.apache.axis2.client.OperationClient.execute(OperationClient.java:163)
          at org.apache.axis2.client.ServiceClient.sendReceive(ServiceClient.java:548)
          at org.apache.axis2.client.ServiceClient.sendReceive(ServiceClient.java:528)
          at org.apache.axis2.rpc.client.RPCServiceClient.invokeBlocking(RPCServiceClient.java:102)
          at client.FileServiceClient.main(FileServiceClient.java:36)

          2009-11-11 00:17 | 茶杯里的葉子

          # re: WebService大講堂之Axis2(4):二進制文件傳輸  回復  更多評論   

          寫的不錯,非常感謝
          2009-11-28 13:24 | SkyStar

          # re: WebService大講堂之Axis2(4):二進制文件傳輸  回復  更多評論   

          做了個DataHandler的client端代碼
          RPCServiceClient serviceClient = new RPCServiceClient();
          Options options = serviceClient.getOptions();
          EndpointReference targetEPR = new EndpointReference("http://localhost:8080/axis2/services/fileService");
          options.setTo(targetEPR);
          DataHandler dh = new DataHandler(new FileDataSource("e:/Sunset.jpg"));
          Object[] opAddEntryArgs = new Object[]{ dh,"e:/fun.jpg" };
          Class[] classes = new Class[]{ Boolean.class };
          QName opAddEntry = new QName("http://service","uploadWithDataHandler");
          System.out.println(serviceClient.invokeBlocking(opAddEntry, opAddEntryArgs,classes)[0]);
          2011-12-14 11:47 | funfenffun

          # re: WebService大講堂之Axis2(4):二進制文件傳輸[未登錄]  回復  更多評論   

          樓主,如何從DataHandler中取出序列化的對象?我這樣取報錯
          DataHandler dh=stub.getUserBytes(gub).get_return();
          ObjectInputStream ois=new ObjectInputStream(dh.getInputStream());
          User u2=(User)ois.readObject();
          報錯: java.lang.ClassCastException
          2012-07-26 16:56 | freefish

          # re: WebService大講堂之Axis2(4):二進制文件傳輸  回復  更多評論   

          你好,我不進行上傳文件操作,只是客戶端調用服務端方法時需要一個byte[]類型的參數,在axis2里可以直接寫參數,
          Object[] opAddEntryArgs = new Object[] {xmlDataByte};
          在xfire里
          Object[] result = client.invoke("test", new Object[]{xmlDataByte});
          這個xmlDataByte就是byte[]數組類型,會報錯
          [B cannot be cast to javax.activation.DataHandler

          我不用wsdl2java的自動生產代碼模式,請問有什么解決方案嗎?
          2013-05-08 00:06 | hl
          主站蜘蛛池模板: 牡丹江市| 历史| 卢龙县| 囊谦县| 贵阳市| 扬中市| 哈巴河县| 湘潭县| 凯里市| 河津市| 肇庆市| 蓝山县| 南宁市| 鹤壁市| 黄骅市| 江城| 通辽市| 台湾省| 日喀则市| 白银市| 天峻县| 祁东县| 新余市| 托克逊县| 繁峙县| 姚安县| 杨浦区| 峨山| 淮南市| 桃源县| 青海省| 茂名市| 准格尔旗| 剑阁县| 黎城县| 武夷山市| 福泉市| 邛崃市| 玉溪市| 凯里市| 宜州市|