程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> How tomcat works 讀書筆記十五 Digester庫

How tomcat works 讀書筆記十五 Digester庫

編輯:C++入門知識

How tomcat works 讀書筆記十五 Digester庫


Digester庫

在前面的幾個章節裡,我們對tomcat裡各個組件的配置完全是使用寫硬編碼的形式完成的。

Context context = new StandardContext();
Loader loader = new WebappLoader();
context.setLoader(loader);
就完成了向context容器裡添加WepappLoader的功能。
這麼做的問題就在於,一旦我想更改配置就必須得重新加載Bootstrap類。
幸運的是tomcat的設計者使用了一種給我靈活的配置方式,即使用xml來記錄tomcat裡各個組件的配置情況。並且使用Digester將xml中的元素轉化為java對象。

Digester是Apache軟件基金會Jakarta項目下的一個開源項目。更多具體的信息請問百度。
這裡我們主要介紹Digester能干什麼。
在apaceh官網上對這個項目的描述如下
XML-to-Java-object mapping utility.
看到了吧,就是咱們在上面說的把xml裡面的元素轉化為java類。

Digester類

先看一個xml 如下


  
    
  
在這個xml裡面,根元素是employee,裡面包含一個元素office,office裡面又包含一個元素address。
在討論Digester如何解析xml前,我們先說兩個概念,模式與規則。
模式:我無法給出一個書面的關於模式的定義。粗略的說在上面的xml中,employee元素的模式是employee;office元素的模式是employee/office;以此類推address元素的模式就是employee/office/address。大家應該大概明白了吧。說白了模式就是路徑。
規則:是org.apache.commons.digester.Rule類的實例。規則指定了在分析xml時遇到某一規則應該執行的動作。說的夠清楚了吧。另外Rule還有begin與end方法。擋在解析到匹配某個模式的元素的開始標簽時會指向begin方法,end還用說嗎?
例如在解析上面的xml時:
1 先解析到了employee元素,此時查找是否有對應的規則與此模式即employee匹配,若有,執行Rule對象的begin方法
2 遇到了office元素,此時查找是否有對應的規則與此模式即employee/office匹配,若有,執行Rule對象的begin方法
3 遇到了address元素的開始標簽,此時查找是否有對應的規則與此模式即employee/office/address匹配,若有,執行Rule對象的begin方法
4 遇到address元素的結束標簽,調用想匹配規則對象的end方法。
5 6自己補全,我不寫了。


Digester預定義的規則

Digester預定義的規則主要有以下幾個。

創建對象

創建對象一共有四種方式
最主要的兩個例子如下:
digester.addObjectCreate("employee",ex15.pyrmont.digestertest.Employee.class);
或者
digester.addObjectCreate("employee","ex15.pyrmont.digestertest.Employee");
第一個參數是模式名,第二個參數可以是類名(String類型),也可以使Class。
還有兩種方式就是在xml中寫明要加載的類。
若xml中如下
className="ex15.pyrmont.digestertest.Employee">
代碼寫成下面的樣子
digester.addObjectCreate("employee","ex15.pyrmont.digestertest.Employee", "className");

employee是類名,程序會按照上面方法的第三個參數去employee元素裡找對應的屬性值作為要加載的類,當然如果找不到那個屬性的話,就是有上面方法的第二個參數來加載。同樣第二個參數可以使String類型的類名也可以使Class。

(employee,office,address都在文章的最後)


設置屬性

digester.addSetProperties("employee");
上面這句代碼做的事情就是:系統找到匹配employee模式的元素後,如果那個元素有屬性,就將相應的屬性值注入到類裡面去。

如果xml中如上,裡面在它所匹配的那個類裡面就至少得有setFirstName,setLastName兩個方法。

調用方法

digester.addCallMethod("employee", "printName");
上面代碼的功能就是找到匹配employee模式的元素後(准確的說是遇到結束標簽後),就調用最先創建的那個類的printName方法。

創建對象之間的聯系

digester.addSetNext("employee/office", "addOffice");
第一個參數的模式應該是這種形式的
firstobject/secondobjcet
上面的代碼的意思就是調用firstobject的addOffice方法,並且以secondobject為參數。當然這兩個object前面都已經產生好了。

下面這個例子讓大家熟悉一下Digester的用法
示例代碼1
package ex15.pyrmont.digestertest;

import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import org.apache.commons.digester.Digester;

public class Test02 {

  public static void main(String[] args) {
    String path = System.getProperty("user.dir") + File.separator +
            "src"+File.separator  + "etc";
    File file = new File(path, "employee2.xml");
    Digester digester = new Digester();
    // add rules
    digester.addObjectCreate("employee", "ex15.pyrmont.digestertest.Employee");
    digester.addSetProperties("employee");    
    digester.addCallMethod("employee", "printName");
    
    digester.addObjectCreate("employee/office", "ex15.pyrmont.digestertest.Office");
    digester.addSetProperties("employee/office");
 
    digester.addSetNext("employee/office", "addOffice");
 
    digester.addObjectCreate("employee/office/address", "ex15.pyrmont.digestertest.Address");
    digester.addSetProperties("employee/office/address");
    digester.addSetNext("employee/office/address", "setAddress");
    try {
      Employee employee = (Employee) digester.parse(file);
      ArrayList offices = employee.getOffices();
      Iterator iterator = offices.iterator();
      System.out.println("-------------------------------------------------");
      while (iterator.hasNext()) {
        Office office = (Office) iterator.next();
        Address address = office.getAddress();
        System.out.println(office.getDescription());
        System.out.println("Address : " +
          address.getStreetNumber() + " " + address.getStreetName());
        System.out.println("--------------------------------");
      }
      
    }
    catch(Exception e) {
      e.printStackTrace();
    }
  }  
}


employee2.xml如下


  
    
  
  
    
  
至於最後的運行結果大家自己猜一下,然後運行一下看看。


RuleSet

這是什麼東西?
大家看代碼就懂了。
package ex15.pyrmont.digestertest;

import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import org.apache.commons.digester.Digester;

public class Test03 {

  public static void main(String[] args) {
    String path = System.getProperty("user.dir") + File.separator +
                "src"+File.separator  + "etc";
    File file = new File(path, "employee2.xml");
    Digester digester = new Digester();
    digester.addRuleSet(new EmployeeRuleSet());  //EmployeeRuleSet是什麼東西?
    try {
      Employee employee = (Employee) digester.parse(file);
    
      ...... 與Test2一樣
    }
    catch(Exception e) {
      e.printStackTrace();
    }
  }
}



package ex15.pyrmont.digestertest;

import org.apache.commons.digester.Digester;
import org.apache.commons.digester.RuleSetBase;

//一定要繼承RuleSetBase
public class EmployeeRuleSet extends RuleSetBase  {

  //復寫    addRuleInstances
  public void addRuleInstances(Digester digester) {
    // add rules
    digester.addObjectCreate("employee", "ex15.pyrmont.digestertest.Employee");
    digester.addSetProperties("employee");  
    
    digester.addObjectCreate("employee/office", "ex15.pyrmont.digestertest.Office");
    digester.addSetProperties("employee/office");
    
    digester.addSetNext("employee/office", "addOffice");
 
    digester.addObjectCreate("employee/office/address","ex15.pyrmont.digestertest.Address");
    digester.addSetProperties("employee/office/address");
    digester.addSetNext("employee/office/address", "setAddress");
  }
}


RuleSetBase就是規則的集合嘛。
Test03與Test02的結果一樣,但是test3的代碼看起來更少一些,就是因為我們把規則都隱藏在了EmployeeRuleSet裡面了。


相關代碼

package ex15.pyrmont.digestertest;

import java.util.ArrayList;

public class Employee {
  private String firstName;
  private String lastName;
  private ArrayList offices = new ArrayList();
    
  public Employee() {
    System.out.println("Creating Employee");
  }
  public String getFirstName() {
    return firstName;
  }
  public void setFirstName(String firstName) {
    System.out.println("Setting firstName : " + firstName);
    this.firstName = firstName;
  }
  public String getLastName() {
    return lastName;
  }
  public void setLastName(String lastName) {
    System.out.println("Setting lastName : " + lastName);
    this.lastName = lastName;
  }
  public void addOffice(Office office) {
    System.out.println("Adding Office to this employee");
    offices.add(office);
  }
  public ArrayList getOffices() {
    return offices;
  }
  public void printName() {
    System.out.println("My name is " + firstName + " " + lastName+"sssssssss");
  }
}


package ex15.pyrmont.digestertest;

public class Office {
  private Address address;
  private String description;
  public Office() {
    System.out.println("..Creating Office");
  }
  public String getDescription() {
    return description;
  }
  public void setDescription(String description) {
    System.out.println("..Setting office description : " + description);
    this.description = description;
  }
  public Address getAddress() {
    return address;
  }
  public void setAddress(Address address) {
    System.out.println("..Setting office address : " + address);
    this.address = address;
  }
}
package ex15.pyrmont.digestertest;

public class Address {
  private String streetName;
  private String streetNumber;
  public Address() {
    System.out.println("....Creating Address");
  }
  public String getStreetName() {
    return streetName;
  }
  public void setStreetName(String streetName) {
    System.out.println("....Setting streetName : " + streetName);
    this.streetName = streetName;
  }
  public String getStreetNumber() {
    return streetNumber;
  }
  public void setStreetNumber(String streetNumber) {
    System.out.println("....Setting streetNumber : " + streetNumber);
    this.streetNumber = streetNumber;
  }
  public String toString() {
    return "...." + streetNumber + " " + streetName;
  }
}


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved