Terry.Li-彬

          虛其心,可解天下之問;專其心,可治天下之學(xué);靜其心,可悟天下之理;恒其心,可成天下之業(yè)。

            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            143 隨筆 :: 344 文章 :: 130 評論 :: 0 Trackbacks
          在實際的應(yīng)用中,不僅需要使用WebService來傳遞簡單類型的數(shù)據(jù),有時也需要傳遞更復(fù)雜的數(shù)據(jù),這些數(shù)據(jù)可以被稱為復(fù)合類型的數(shù)據(jù)。數(shù)組與類(接口)是比較常用的復(fù)合類型。在Axis2中可以直接使用將WebService方法的參數(shù)或返回值類型聲明成數(shù)組或類(接口)。但要注意,在定義數(shù)組類型時只能使用一維數(shù)組,如果想傳遞多維數(shù)組,可以使用分隔符進(jìn)行分隔,如下面的代碼所示:

          String[] strArray = new String[]{ "自行車,飛機(jī),火箭","中國,美國,德國", "超人,蜘蛛俠,鋼鐵俠" } ;

              上面的代碼可以看作是一個3*3的二維數(shù)組。

              在傳遞類的對象實例時,除了直接將數(shù)組類型聲明成相應(yīng)的類或接口,也可以將對象實例進(jìn)行序列化,也就是說,將一個對象實例轉(zhuǎn)換成字節(jié)數(shù)組進(jìn)行傳遞,然后接收方再進(jìn)行反序列化,還原這個對象實例。

              下面的示例代碼演示了如何傳遞數(shù)組與類(接口)類型的數(shù)據(jù),并演示如何使用字節(jié)數(shù)組上傳圖像。本示例的客戶端代碼使用JavaC#編寫。要完成這個例子需要如下幾步:

          一、實現(xiàn)服務(wù)端代碼

              ComplexTypeService是一個WebService類,該類的代碼如下:

          import java.io.FileOutputStream;
          import data.DataForm;

          public class ComplexTypeService
          {
              
          //  上傳圖像,imageByte參數(shù)表示上傳圖像文件的字節(jié),
              
          //  length參數(shù)表示圖像文件的字節(jié)長度(該參數(shù)值可能小于imageByte的數(shù)組長度)
              public boolean uploadImageWithByte(byte[] imageByte, int length)
              {
                  FileOutputStream fos 
          = null;
                  
          try
                  {
                      
          //  將上傳的圖像保存在D盤的test1.jpg文件中
                      fos = new FileOutputStream("d:\\test1.jpg");
                      
          //  開始寫入圖像文件的字節(jié)
                      fos.write(imageByte, 0, length);
                      fos.close();
                  }
                  
          catch (Exception e)
                  {
                      
          return false;
                  }
                  
          finally
                  {
                      
          if (fos != null)
                      {
                          
          try
                          {
                              fos.close();
                          }
                          
          catch (Exception e)
                          {

                          }
                      }
                  }
                  
          return true;
              }
              
          //  返回一維字符串?dāng)?shù)組
              public String[] getArray()
              {
                  String[] strArray 
          = new String[]{ "自行車""飛機(jī)""火箭" };
                  
          return strArray;
              } 
              
          //  返回二維字符串?dāng)?shù)組
              public String[] getMDArray()
              {
                  String[] strArray 
          = new String[]{ "自行車,飛機(jī),火箭","中國,美國,德國""超人,蜘蛛俠,鋼鐵俠" } ;
                  
          return strArray;
              }
              
          //  返回DataForm類的對象實例
              public DataForm getDataForm()
              {
                  
          return new DataForm();
              }
              
          //  將DataForm類的對象實例序列化,并返回序列化后的字節(jié)數(shù)組
              public byte[] getDataFormBytes() throws Exception 
              {
                  java.io.ByteArrayOutputStream baos 
          = new java.io.ByteArrayOutputStream();
                  java.io.ObjectOutputStream oos 
          = new java.io.ObjectOutputStream(baos);
                  oos.writeObject(
          new DataForm());        
                  
          return baos.toByteArray();
              }    
          }

           

          二、實現(xiàn)DataForm

              DataForm是要返回的對象實例所對應(yīng)的類,該類的實現(xiàn)代碼如下:

          package data;

          public class DataForm implements java.io.Serializable
          {
              
          private String name = "bill";
              
          private int age = 20;

              
          public String getName()
              {
                  
          return name;
              }
              
          public void setName(String name)
              {
                  
          this.name = name;
              }
              
          public int getAge()
              {
                  
          return age;
              }
              
          public void setAge(int age)
              {
                  
          this.age = age;
              }
          }

           

          三、發(fā)布WebService

              由于本示例的WebService類使用了一個Java類(DataForm類),因此,在發(fā)布WebService之前,需要先將DataForm.class文件復(fù)制到<Tomcat安裝目錄>\webapps\axis2\WEB-INF\classes\data目錄中,然后將ComplexTypeService.class文件復(fù)制到<Tomcat安裝目錄>\webapps\axis2\WEB-INF\pojo目錄中,最后啟動Tomcat(如果Tomcat已經(jīng)啟動,由于增加了一個DataForm類,因此,需要重新啟動Tomcat)。

          四、使用Java編寫調(diào)用WebService的客戶端代碼

              在客戶端仍然使用了RPC的調(diào)用方式,代碼如下:

          package client;

          import javax.xml.namespace.QName;
          import org.apache.axis2.addressing.EndpointReference;
          import org.apache.axis2.client.Options;
          import org.apache.axis2.rpc.client.RPCServiceClient;

          public class ComplexTypeRPCClient
          {

              
          public static void main(String[] args) throws Exception
              {
                  RPCServiceClient serviceClient 
          = new RPCServiceClient();
                  Options options 
          = serviceClient.getOptions();
                  EndpointReference targetEPR 
          = new EndpointReference(
                          
          "http://localhost:8080/axis2/services/ComplexTypeService");
                  options.setTo(targetEPR);
                  
          // 下面的代碼調(diào)用uploadImageWithByte方法上傳圖像文件
                  /////////////////////////////////////////
                  
          // 打開圖像文件,確定圖像文件的大小
                  java.io.File file = new java.io.File("f:\\images.jpg");
                  java.io.FileInputStream fis 
          = new java.io.FileInputStream("f:\\images.jpg");
                  
          // 創(chuàng)建保存要上傳的圖像文件內(nèi)容的字節(jié)數(shù)組
                  byte[] buffer = new byte[(int) file.length()];
                  
          // 將圖像文件的內(nèi)容讀取buffer數(shù)組中
                  int n = fis.read(buffer);
                  System.out.println(
          "文件長度:" + file.length());
                  Object[] opAddEntryArgs 
          = new Object[]{ buffer, n };
                  Class[] classes 
          = new Class[]{ Boolean.class };
                  QName opAddEntry 
          = new QName("http://ws.apache.org/axis2","uploadImageWithByte");
                  fis.close();
                  
          // 開始上傳圖像文件,并輸出uploadImageWithByte方法的返回傳
                  System.out.println(serviceClient.invokeBlocking(opAddEntry,opAddEntryArgs, classes)[0]);
                  
          /////////////////////////////////////////
                  
                  
          // 下面的代碼調(diào)用了getArray方法,并返回一維String數(shù)組
                  /////////////////////////////////////////  
                  opAddEntry = new QName("http://ws.apache.org/axis2""getArray");
                  String[] strArray 
          = (String[]) serviceClient.invokeBlocking(opAddEntry,
                                      new
           Object[]{}, new Class[]{String[].class })[0];
                  
          for (String s : strArray)
                      System.out.print(s 
          + "  ");
                  System.out.println();
                  
          ////////////////////////////////////////
                  

                  
          // 下面的代碼調(diào)用了getMDArray方法,并返回一維String數(shù)組
                  /////////////////////////////////////////  
                  opAddEntry = new QName("http://ws.apache.org/axis2""getMDArray");
                  strArray 
          = (String[]) serviceClient.invokeBlocking(opAddEntry, new Object[]{},
                                                                    new
           Class[]{String[].class})[0];
                  
          for (String s : strArray)
                  {
                      String[] array 
          = s.split(",");
                      
          for(String ss: array)
                          System.out.print(
          "<" + ss + "");
                      System.out.println();
                  }
                  System.out.println();
                  
          ////////////////////////////////////////

                  
          // 下面的代碼調(diào)用了getDataForm方法,并返回DataForm對象實例
                  /////////////////////////////////////////  
                  opAddEntry = new QName("http://ws.apache.org/axis2""getDataForm");
                  data.DataForm df 
          = (data.DataForm) serviceClient.invokeBlocking(opAddEntry, new Object[]{},
                                                                           
          new Class[]{data.DataForm.class})[0];
                  System.out.println(df.getAge());
                  
          /////////////////////////////////////////
                  
                  
          // 下面的代碼調(diào)用了getDataFormBytes方法,并返回字節(jié)數(shù)組,最后將返回的字節(jié)數(shù)組反序列化后,轉(zhuǎn)換成DataForm對象實例
                  /////////////////////////////////////////          
                  opAddEntry = new QName("http://ws.apache.org/axis2""getDataFormBytes");
                  buffer 
          = (byte[]) serviceClient.invokeBlocking(opAddEntry, new Object[]{}, new Class[]{byte[].class})[0];
                  java.io.ObjectInputStream ois 
          = new java.io.ObjectInputStream(
                          
          new java.io.ByteArrayInputStream(buffer));
                  df 
          = (data.DataForm) ois.readObject();
                  System.out.println(df.getName());
                  
          //////////////////////////////////////////
              }
          }

              運行上面的程序,將輸出如下的內(nèi)容:

          文件長度:3617

          true

          自行車 飛機(jī) 火箭 

          <自行車> <飛機(jī)> <火箭>

          <中國> <美國> <德國>

          <超人> <蜘蛛俠> <鋼鐵俠>

          20

          bill

          五、使用C#編寫調(diào)用WebService的客戶端代碼

              Visual Studio中使用WebService就簡單得多。假設(shè)引用WebService時的引用名為complexType,則下面的代碼調(diào)用了uploadImageWithByte方法來上傳圖像文件。在Visual Studio引用WebService時,uploadImageWithByte方法多了兩個out參數(shù),在使用時要注意。

          complexType.ComplexTypeService cts = new WSC.complexType.ComplexTypeService();
          System.IO.FileStream fs 
          = new System.IO.FileStream(@"f:\images.jpg", System.IO.FileMode.Open);
          byte[] buffer = new byte[fs.Length];
          fs.Read(buffer, 
          0, (int)fs.Length);
          bool r;
          bool rs;
          cts.uploadImageWithByte( buffer, (
          int)fs.Length, trueout r, out rs);

              在獲得二維數(shù)組時,可以將數(shù)據(jù)加載到DataGridView或其他類似的控件中,代碼如下:

          String[] strArray = cts.getMDArray();
          for (int i = 0; i < strArray.Length; i++)
          {
              
          //  用正則表達(dá)式將帶分隔符的字符串轉(zhuǎn)換成String數(shù)組
              String[] columns = strArray[i].Split(',');
              
          //  如果DataGridView的表頭不存在,向DataGridView控件添加三個帶表頭的列
              if (dataGridView1.Columns.Count == 0)
                  
          for (int j = 0; j < columns.Length; j++)
                      dataGridView1.Columns.Add(
          "column" + (j + 1).ToString(), "" + (j + 1).ToString());
              
          //  添加行
              dataGridView1.Rows.Add(1);
              
          for(int j = 0; j < columns.Length; j++)
              {
                  dataGridView1.Rows[i].Cells[j].Value 
          = columns[j];                       
              }                
          }

              DataGridView控件添加數(shù)據(jù)后的效果如圖1所示。



          圖1 

           

              對于其他的WebService方法的調(diào)用都非常簡單,讀者可以自己做這個實驗。

              要注意的是,由于.netjava序列化和反序列化的差異,通過序列化的方式傳遞對象實例只使用于客戶端與服務(wù)端為同一種語言或技術(shù)的情況,如客戶端和服務(wù)端都使用Java來編寫。

              如果讀者要上傳大文件,應(yīng)盡量使用FTP的方式來傳遞,而只通過WebService方法來傳遞文件名等信息。這樣有助于提高傳輸效率。

           

          posted on 2009-01-05 20:13 禮物 閱讀(2463) 評論(0)  編輯  收藏 所屬分類: web service
          主站蜘蛛池模板: 大方县| 巍山| 青岛市| 齐齐哈尔市| 台安县| 定襄县| 云龙县| 达拉特旗| 临桂县| 阳谷县| 安龙县| 大化| 集贤县| 德化县| 会同县| 潞西市| 开阳县| 申扎县| 银川市| 苏州市| 康保县| 沾益县| 正安县| 兴宁市| 普安县| 七台河市| 乐平市| 探索| 梧州市| 阿拉善左旗| 灵武市| 长春市| 久治县| 沂南县| 海晏县| 内乡县| 宣汉县| 佛教| 方城县| 白银市| 禹城市|