隨筆 - 312, 文章 - 14, 評論 - 1393, 引用 - 0
          數據加載中……

          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 銀河使者 閱讀(22558) 評論(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
          主站蜘蛛池模板: 茶陵县| 共和县| 永胜县| 中牟县| 香格里拉县| 屯留县| 翼城县| 城口县| 平顶山市| 宜川县| 大石桥市| 安丘市| 讷河市| 北海市| 曲麻莱县| 天峨县| 榕江县| 保定市| 七台河市| 驻马店市| 新泰市| 彭水| 米脂县| 株洲县| 沧源| 东台市| 元氏县| 井研县| 四子王旗| 伊春市| 西平县| 汶川县| 房山区| 根河市| 剑阁县| 宁强县| 沁源县| 星座| 东港市| 洞头县| 青冈县|