1. 程式人生 > >AXIS2中OMElement和Java物件之間的轉換 分享

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反應一下