axis 傳輸 簡單對象,複雜對象,List,Map等

有問題聯繫小白同學:[email protected](MSN)

那些java的對象是可以序列化爲xml的, 並且可以從xml反序列化爲java對象的?
那些對象與xml之間不能夠序列化和反序列化?
在開發的時候應該注意哪些問題?

根據我的理解, 有如下幾種對象:
1)axis1.2內在支持的幾種對象類型。
          這幾種內在支持的對象包括:
          java基本類型 : int, float,,,,
          基本類型包裝類 : Integer, Float, Long...
          還有String, Date, Calendar, BigDecimal, BigInteger, List, Map.
     凡是這些內在支持的對象, 不管他們作爲某個Service的input 還是 output, 我們在服務端的axis1.2的WEB-INF/server-config.wsdd的該Service的定義中都不需要加入 <beanMapping>或者是<typeMapping>的聲明。

2)簡單的javabean對象類型。
       對於簡單的javabean對象, 比如對象中所有的field都是上面提到的基本類型。 axis1.2也提供了很好的支持。
       比如:
       public class JavaBeanInputService { 
           public void testJavaBeanInput(MyBean bean) {
               ......
          }
       }
         由於MyBean是一個自定義的JavaBean對象, 所以在server-config.wsdd中就必須加上<beanMapping ...../>的聲明, 讓axis知道怎麼把request中xml數據deserialize爲MyBean對象, 又如何把MyBean對象serialize爲xml數據作爲response.用wtp自動爲JavaInputService生成的wsdl中, MyBean是作爲一個complexType在wsdl中定義的。

3)複雜一點的JavaBean對象。
        比如JavaBean對象中的一些field又是自定義的JavaBean,  這種情況下, wsdl中生成的complextype會有多個, 而在wsdd定義的<beanMapping .../>也會有多個, axis1.2支持起來都是易如反掌。

4)普通的非javabean對象。
      對於一些不是javaBean的對象, wtp也會替你生成對應的wsdl的ComplexType, 依據的是對象的getter方法。但是顯然這是不夠的。 比如說有些對象的數據結構比較複雜, 像java.util.HashMap(雖然這個已經被axis內在支持了。)這些對象如果想要把自己的狀態進行serialization和 deserialization, 就得自己編寫serializer和deserializer,  而且還必須保證wsdl中的該complexType的描述是正確的。

5)java中的List, Map問題。
       試想一下如果一個service的樣子是這樣子的。


       public class ListService{
             public List listTest(List list) {
                    for(Iterator iter = list.iterator(); iter.hasNext(); ) {
                           (MyBean)list.next();//進行強轉。
                    }
              }
       }
        用wtp爲這個service生成的wsdl中把list映射爲一個type爲xsd:anyType的maxOccurs="unbound"的complexType。這樣的話客戶端生成的Stub中的接口中類似於:
        public interface ListService{
             public Object[] listTest(Object[] list) ;
        }
        如果Client端用戶傳遞的入口參數是String[],那麼在服務端執行的必然會發生轉型錯誤。
        因此,在webservice中把List, Map作爲service的input, output的做法都是不可行的。至少在jdk1.4的版本中是這樣的。
       
一個更好的方法就是:

6)java中的數組。
      上例中的ListService如果改造爲下面這樣,基本上就沒有上面提到的問題了。
      public class ListService{
             public MyBean[] listTest(MyBean[] list) {
                   ...
             }
       }
        這樣在wsdl中, MyBean被映射爲一種ComplexType,MyBean[]爲映射爲ComplexType爲映射爲可以重複出現的MyBean類型。在客戶端的 Stub的接口跟這個也是類似的。從而也成功地避免了List, Map中型別問題。


       要注意的是,在server-config.wsdd中需要配置<arrayMapping.../>
       似乎List, Map的問題用數組就可以解決了。事實上就是如此。但是還得注意的是:
   javabean裏邊也不能含有List. 如果MyBean跟其它某個對象是1:n的關係,那麼也只能寫成數組的形式,而不能是List的形式。

7)特殊對象java.lang.Object
       如果一個service寫成了下面的形式:
       public class ObjectService{
             public Object objInvoke(Object obj) {
                   ...
             }
       }
        想把它發佈爲web service, 那麼幾乎是不太可能的。遇到obj類型,wsdl裏邊只能定義爲xsd:anyType類型,而這種類型如果給客戶端返回一個比如MyBean類型,那麼 必然會導致xml的serialization的失敗。結論就是:

 

         web service中如果input 或者是output是java.lang.Object類型,那麼將會導致嚴重問題。
        
        上 面的幾種對象類型基本上能夠涵蓋將java class發佈爲web service時需要考慮的對象類型。可以看到開發web service的時候,並不是所有的java都能夠輕而易舉地發佈爲web service, 一些複雜的類的對象類型,還有一些特殊的對象類型都是要考慮的。最後一個問題是:子類是否也很容易的得到序列化和反序列化?
         答案是肯定的。如下的Service:
          public class PolymorphicService{
             public MyBean objInvoke(MyBean obj) {
                   ...
             }
         }
          客戶端的Stub如下:
          public class PolymorphicServiceStub{
             public MyBean objInvoke(MyBean obj) {

                   ...
             }
         }

         如果在客戶端調用stub時傳入的不是MyBean類的對象,而是它的子類的一個對象,那麼也可以被序列化而傳到服務端。同樣,如果服務端返回的對象是MyBean類的字類的一個對象,也可以成功的被序列化到客戶端。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章