AXIS2中OMElement和Java對象之間的轉換 分享

最近在使用AXIS2部署Web Service,關於如果使用axis2部署Web Service的方法不想在這裏多說,網站有很多相關的文章,這裏只想談談AXIOM對象與Java中的對象的轉換方法。

關於AXIOM的介紹,下面這個片段已經說得很明白了:

AXIOM

AXIs 對象模型 (AXIOM) 是一個 XML 對象模型,設計用於提高 XML 處理期間的內存使用率和性能,基於 Pull 解析。通過使用 Streaming API for XML (StAX) Pull 解析器,AXIOM(也稱爲 OM)可以控制解析過程,以提供延遲構建支持。延遲構建是指 AXIOM 不完全構建對象模型,模型的其餘部分基於用戶的需求構建。以下示例對此概念進行了說明:

假定某個用戶需要從 XML 輸入流中獲得第一個人的 <Location> 元素值,AXIOM 構建的對象模型將一直包含到<Location> 元素結束的內容,而讓其他內容保留在流中:


清單 1. 對象模型的 AXIOM 部分構建

<Persons>
  <Person>
     <Name>Dihini Himahansi</Name>
     <Sex>Female</Sex>
     <Location>Colombo, Sri Lanka</Location>  
     <--- Object model is being built only up to this point
  </Person>
  <Person>
     <Name>Thushari Damayanthi</Name>
     <Sex>Female</Sex>
     <Location>Elpitiya, Sri Lanka</Location>
  </Person>
</Persons>

這裏的優勢在於,儘可能僅使用能滿足用戶的需求的內存。如果用戶希望訪問較大的文檔中前面的數個字節或數千字節,則延遲構建功能將改善該應用程序的內存需求情況。

可以從任何元素獲得 StAX 事件,而不管是否完整構建了對象模型。在有些情況下,Axis 2 中的此功能非常有用。例如,當 Axis2 作爲中介傳遞時,如果需要僅讀取 SOAP 消息的 Header,AXIOM 將防止其讀取整個 SOAP 消息,使其具有很高的內存效率。另一個例子是,當 Web 服務實現能夠直接使用 StAX 事件時,由於採用了 AXIOM,Web 服務所需的內存非常小。

此外,AXIOM 內置了消息傳輸優化機制(Message Transfer Optimization Mechanism,MTOM)支持。對於 AXIOM 體系結構,可以通過實現 AXIOM 接口並將其插入到 Axis2 中來執行自己的對象模型。

由於 AXIOM 最初是作爲 Axis2 的對象模型而開發的,因此 AXIOM 提供了構建於基礎 AXIOM API 之上的 SOAP 接口。這允許您使用 envelope.getHeaders 和 envelope.getBody 之類的便利方法查看 SOAP。

AXIS2會將Web Service方法中的參數或返回值中的自定義對象、數組、List等類型統一映射爲OMElement類型,這就我們需要編寫OMElement與自定義類型質檢的轉換方法,下面給出幾個常用的方法:

CASE1:自定義對象生成OMElement方法:

  Person man = new Person();
  man.setName("Warlaze");
  man.setAge(25);
  man.setAddress("Bei jing");
  man.setPhonenum("13900000000");
  javax.xml.stream.XMLStreamReader reader = BeanUtil.getPullParser(man);
  StreamWrapper parser = new StreamWrapper(reader);
  StAXOMBuilder stAXOMBuilder =OMXMLBuilderFactory.createStAXOMBuilder(OMAbstractFactory.getOMFactory(), parser);
  OMElement element = stAXOMBuilder.getDocumentElement();

CASE2:List或Array類型生成OMElement方法:

  List<Person> list = new ArrayList<Person>();
  list.add(man);
  list.add(man);
  OMElement omElement = BeanUtil.getOMElement(new QName("root"), list
    .toArray(), new QName("person"), false, null);

CASE3:解析包含基本類型的List或Array生成的OMElement的方法:

 private static List<String> getResults(OMElement element) {
  if(element == null){
   return null;
  }
  Iterator iterator = element.getChildElements();
  List<String> list = new ArrayList<String>();
  while (iterator.hasNext()) {
   OMNode omNode = (OMNode) iterator.next();
   if (omNode.getType() == OMNode.ELEMENT_NODE) {
    OMElement omElement = (OMElement) omNode;
    if (omElement.getLocalName().equals("string")) {
     String temp = omElement.getText().trim();
     System.out.println(temp);
     list.add(temp);
    }
   }
  }
  return list;
 }

CASE4:解析包含自定義Java類型的List或Array的方法:

  private static List<Person> getResults(OMElement element) throws AxisFault {
  if (element == null) {
   return null;
  }
  Iterator iterator = element.getChildElements();
  List<Person> list = new ArrayList<Person>();
  while (iterator.hasNext()) {
   OMNode omNode = (OMNode) iterator.next();
   if (omNode.getType() == OMNode.ELEMENT_NODE) {
    OMElement omElement = (OMElement) omNode;
    if (omElement.getLocalName().toLowerCase().equals("person")) {
     Person person = (Person) BeanUtil.processObject(omElement,
       Person.class, null, true,
       new DefaultObjectSupplier());
     list.add(person);
    }
   }
  }
  return list;
 }

 

 

 

ps:

在現在項目中使用axis2,發現其源碼有一個問題:

在org.apache.axis2.databinding.utils.BeanUtil.java-500 line
 String partsLocalName = parts.getLocalName();
                PropertyDescriptor prty = (PropertyDescriptor)properties.get(
                        partsLocalName.toLowerCase());
                if (prty != null) {...

可以看到,在第500行進行了一個toLowerCase()轉換,導致自定義類型的轉換出現bean屬性丟失,

將它去掉,重新打包就可以正常運行了;

不明白爲什麼axis2工作小組要進行這樣處理呢;

不知道這算不算一個bug,總不能就規定我們只能使用全部小寫字母來定義bean屬性吧,有違java編碼規範啊;

看來要給apache反應一下

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