本站首页    管理页面    写新日志    退出


«August 2025»
12
3456789
10111213141516
17181920212223
24252627282930
31


公告
 本博客在此声明所有文章均为转摘,只做资料收集使用。

我的分类(专题)

日志更新

最新评论

留言板

链接

Blog信息
blog名称:
日志总数:1304
评论数量:2242
留言数量:5
访问次数:7598368
建立时间:2006年5月29日




[Apache(jakarta)]关于使用commons-betwixt组件实现xml信息-->Java Bean的转化的一些感受
软件技术

lhwork 发表于 2006/9/27 10:10:51

实现这一功能的核心类是BeanReader,如果你看过betwixt的源代码,你会发现public class BeanReader extends Digester{}如果你细看一下BeanReader的源代码,你会发现betwixt在处理xml-->JavaBean转化时其实是调用Digester这个类的parse方法。但除了此方式可以实现转化的功能以外,BeanReader自身也有一些新的机制对xml进行转化,完善了Digester的很多欠缺功能,让转化更加方便。首先,来看一下BeanReader完全使用Digester的parse方法进行转化的流程。(其实觉得说是Digester怎样处理转化更为恰当)1。xml信息******************examples.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>******************examples.xml*************************2。定义实体对象Person和AddressBook******************Person.java**************************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);       }          }******************Person.java********************************************AddressBook.java*********************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();        }    }}******************AddressBook.java*********************3。实现转化功能******************AddressBookDigester.java**************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); }}******************AddressBookDigester.java**************运行结果如下:Address book has 2 entriesPerson #1  category=acquaintance  name=Gonzo  email (type business) : gonzo@muppets.comPerson #2  category=rolemodel  name=Kermit  email (type business) : kermit@muppets.com  email (type home) : kermie@acme.com其次,再看看不使用Digester的add***Method()方法,对转化属性进行配置的方式。1。定义实体类*************************PersonBean.java****************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 + "']";    }}*************************PersonBean.java****************2.person.xml文件*************************person.xml*********************<beans>  <personbean>    <age>22</age>    <name>luna</name>  </personbean></beans>*************************person.xml*********************3。实现转化功能*************************ReadApp.java*******************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);    }    }*************************ReadApp.java*******************运行结果:PersonBean[name='luna',age='22']说明几点:Digester类的parse()是xml向javabean转化的核心方法,两者的最大区别是,前者通过详细的add***()方法,告诉了BeanReader的转化步骤,而后者则是用registerBeanClass()注册将要转化成的bean对象类型,而其中的方法调用则是BeanReader自动去按号入座完成的。而后者也一次只能转化一个bean对象,可采用迭代的方法对多哥对象进行操作。前者适用于在已经知道bean类型及具体属性的情况下,可以用add***()一步步的设定转化的步骤,而如果产生的对象是预先未知的,只有在知道结果的情况下才知道它的属性,这个时候只要在后者方法中使用registerBeanClass()把该类注册给betwxit,剩下的功能,这个组件就可以自动完成了 。


阅读全文(2026) | 回复(0) | 编辑 | 精华
 



发表评论:
昵称:
密码:
主页:
标题:
验证码:  (不区分大小写,请仔细填写,输错需重写评论内容!)



站点首页 | 联系我们 | 博客注册 | 博客登陆

Sponsored By W3CHINA
W3CHINA Blog 0.8 Processed in 0.328 second(s), page refreshed 144763621 times.
《全国人大常委会关于维护互联网安全的决定》  《计算机信息网络国际联网安全保护管理办法》
苏ICP备05006046号