實現xml資訊到Java Bean的轉化

來源:互聯網
上載者:User
xml

  本文主要是關於使用commons-betwixt組件實現xml資訊到Java Bean的轉化的一些感受,實現這一功能的核心類是BeanReader,如果你看過betwixt的原始碼,你會發現

public class BeanReader extends Digester{}

      如果你細看一下BeanReader的原始碼,betwixt在處理xml-->JavaBean轉化時其實是調用Digester這個類的parse方法。但除了此方式可以實現轉化的功能以外,BeanReader自身也有一些新的機制對xml進行轉化,完善了Digester的很多欠缺功能,讓轉化更加方便。

  首先,來看一下BeanReader完全使用Digester的parse方法進行轉化的流程。(其實覺得說是Digester怎樣處理轉化更為恰當)

  1。xml資訊

<address-book>
  <person id="1" category="acquaintance" try="would be ignored">
    <name>Gonzo</name>
    <email type="business">gonzo@muppets.com</email>
    <gender result="the whole tag would be ignored">male</gender>
  </person>
  <person id="2" category="rolemodel">
    <name>Kermit</name>
    <email type="business">kermit@muppets.com</email>
    <email type="home">kermie@acme.com</email>
  </person>
</address-book>

  2。定義實體物件Person和AddressBook

import java.util.HashMap;
import java.util.Iterator;
public class Person {
 private int id;
   private String category;
   private String name;
   private HashMap emails = new HashMap();
     
   /**
    * A unique id for this person. Note that the Digester automatically
    * converts the id to an integer.
    */
   public void setId(int id) {
       this.id = id;
   }
  
   public void setCategory(String category) {
       this.category = category;
   }
  
   public void setName(String name) {
       this.name = name;
   }
  
   /** we assume only one email of each type... */
   public void addEmail(String type, String address) {
       emails.put(type, address);
   }
  
 
   public void print() {
       System.out.println("Person #" + id);
       System.out.println("  category=" + category);
       System.out.println("  name=" + name);
      
       for(Iterator i = emails.keySet().iterator(); i.hasNext(); ) {
           String type = (String) i.next();
           String address = (String) emails.get(type);
          
           System.out.println("  email (type " + type + ") : " + address);
       }
      
   }

import java.util.Iterator;
import java.util.LinkedList;

public class AddressBook {
 LinkedList person = new LinkedList();
   
 public LinkedList getPerson(){
  return person;
 }
    public void addPerson(Person p) {
        person.addLast(p);
    }
   
    public void print() {
        System.out.println("Address book has " + person.size() + " entries");

        for(Iterator i = person.iterator(); i.hasNext(); ) {
            Person p = (Person) i.next();
            p.print();
        }
    }

  3。實現轉化功能

public class AddressBookDigester{
public static void main(String[] args) throws IOException, SAXException, IntrospectionException{
 
  // 建立一個BeanReader執行個體
  BeanReader reader = new BeanReader();
  // 建立AddressBook執行個體,並將其壓入棧頂。
  AddressBook book = new AddressBook();
  reader.push(book);
  // 增加規則
  addRules(reader);
 
  reader.parse(new File("examples.xml"));
  book.print();
 
 }
private static void addRules(BeanReader d) {
  // 當遇到<person>時,建立類Person的一個執行個體,並將其壓入棧頂
  d.addObjectCreate("address-book/person", Person.class);
  // 將<person>標籤的屬性(attribute)與棧頂Person類對象的屬性(property)設定方法根據各自的名字進行映射,(例如,將
標籤屬性id與屬性設定方法setId進行映射,將標籤屬性category與屬性設定方法setCategory進行映射),然後將屬性的值作參數傳遞給執行相
應的方法。
  // 如果某標籤屬性沒法通過名字找到相應的屬性設定方法,則此標籤屬性被忽略(如example.xml中第一個<person>的try屬
性)。
  d.addSetProperties("address-book/person");
  // 調用第二棧頂對象(AddressBook執行個體)的addPerson方法,以棧對象(Person執行個體)的對象為參數
  d.addSetNext("address-book/person", "addPerson");
  // 當遇到<person>的子項目<name>時,調用棧頂對象(Person執行個體)的setName方法。
  // 此處addCallMethod方法的第一參數是規則,第二個參數是方法的名字,第三個是參數的數量(為0時,表示只有一個參數
,且參數的值是元素的內容)
  d.addCallMethod("address-book/person/name", "setName", 0);
  // 當遇到<person>的子項目<email>時,調用棧頂對象(Person執行個體)的addEmail
  // 方法,addEmail方法有兩個參數,取值分別來自<email>的屬性type的值和<email>本身的內容。
  // 此處addCallParam方法的第一參數是規則,第二個參數是指明被呼叫者法(addEmail)參數的序號,第三個是參數為字串
時指屬性的名字)
  d.addCallMethod("address-book/person/email", "addEmail", 2);
  d.addCallParam("address-book/person/email", 0, "type");
  d.addCallParam("address-book/person/email", 1);
 }
}

  運行結果如下:

Address book has 2 entries
Person #1
  category=acquaintance
  name=Gonzo
  email (type business) : gonzo@muppets.com
Person #2
  category=rolemodel
  name=Kermit
  email (type business) : kermit@muppets.com
  email (type home) : kermie@acme.com

  其次,再看看不使用Digester的add***Method()方法,對轉化屬性進行配置的方式。

  1。定義實體類

public class PersonBean {
   
    private String name;
    private int age;
   
    /** Need to allow bean to be created via reflection */
    public PersonBean() {}
   
    public PersonBean(String name, int age) {
        this.name = name;
        this.age = age;
    }
   
    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;
    }
   
    public String toString() {
        return "PersonBean[name='" + name + "',age='" + age + "']";
    }
}

  2.person.xml檔案

<beans>
  <personbean>
    <age>22</age>
    <name>luna</name>
  </personbean>
</beans>
 3。實現轉化功能

import java.io.StringReader;
import org.apache.commons.betwixt.io.BeanReader;
public class ReadApp {
   
    public static final void main(String args[]) throws Exception{
       
         // 初始化BeanReader並對其進行配置
  BeanReader reader = new BeanReader();
  reader.getXMLIntrospector().getConfiguration()
    .setAttributesForPrimitives(false);
  reader.getBindingConfiguration().setMapIDs(false);
  // 註冊bean,告訴betwixt把xml轉化成什麼bean
  reader.registerBeanClass("personbean", PersonBean.class);
  // 得到一個Object對象並列印
  PersonBean person = (PersonBean)reader.parse(new File("person.xml"));
  System.out.println(person);
    }
   
}

運行結果:
PersonBean[name='luna',age='22']  

說明幾點:

  Digester類的parse()是xml向javabean轉化的核心方法,兩者的最大區別是,前者通過詳細的add***()方法,告訴了BeanReader的轉化步驟,而後者則是用registerBeanClass()註冊將要轉化成的bean物件類型,而其中的方法調用則是BeanReader自動去按號入座完成的。而後者也一次只能轉化一個bean對象,可採用迭代的方法對多哥對象進行操作。

  前者適用於在已經知道bean類型及具體屬性的情況下,可以用add***()一步步的設定轉化的步驟,而如果產生的對象是預先未知的,只有在知道結果的情況下才知道它的屬性,這個時候只要在後者方法中使用registerBeanClass()把該類註冊給betwxit,剩下的功能,這個組件就可以自動完成了 。


 



相關文章

Alibaba Cloud 10 Year Anniversary

With You, We are Shaping a Digital World, 2009-2019

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。