如何轻松实现JavaBeans到XML的相互转换

发表于:2007-06-22来源:作者:点击数: 标签:
为了灵活的满足Web应用和Web services 需求 的变化,Java和XML的轻便性和可扩展性使它们成为解决这一问题的理想选择。 SAX (Simple API for XML), DOM (document.nbspObject Model), XSL (Extensible Stylesheet Language), XSLT (XSL Transformations), SO

   
  为了灵活的满足Web应用和Web services需求的变化,Java和XML的轻便性和可扩展性使它们成为解决这一问题的理想选择。

SAX (Simple API for XML), DOM (document.nbspObject Model), XSL (Extensible Stylesheet Language), XSLT (XSL Transformations), SOAP (Simple Object Aclearcase/" target="_blank" >ccess Protocol), and BML (Bean Markup Language)是XML领域内的相关技术。本文集合了Java和XML轻便和可扩展的优点,但又不需要开发人员了解上述的相关技术。
  在Java分布式应用中使用远程方法调用(RMI),而不是直接用底层的socket或其它网络链接代码。EJB技术也使开发人员从transaction,recovery, activation等底层机制中解放出来。同样,使用本文的JavaBean-XML映射组件,开发人员也不用直接处理与XML有关的APIs。
  
  组件的编写
  BeanXMLMapping组件实现了从JavaBean到XML文件的相互转换。借助于JavaBean的内省机制,XML解析器和DOM APIs,您可以编写toXML()方法来实现从JavaBean到XML文件的转换,以及fromXML()方法实现从XML文件到JavaBean的转换.
  列表1展示BeanXMLMapping组件一种可能的实现。程序中使用JOX(Java Objects in XML)类库。当然您也可以使用其它的APIs来实现BeanXMLMapping组件,这里选用JOX是因为比较简单并且可以重用。
  
  列表1 BeanXMLMapping组件
  import com.wutka.jox.*;
  import java.io.ByteArrayInputStream;
  import java.io.ByteArrayOutputStream;
  import java.io.IOException;
  
  public class BeanXMLMapping {
  
   /**
  * Retrieves a bean object for the
  * received XML and matching bean class
  */
   public static Object fromXML(String xml, Class className) {
  ByteArrayInputStream xmlData = new ByteArrayInputStream(xml.getBytes());
  JOXBeanInputStream joxIn = new JOXBeanInputStream(xmlData);
  try {
   return (Object) joxIn.readObject(className);
  } catch (IOException exc) {
   exc.printStackTrace();
   return null;
  } finally {
   try {
    xmlData.close();
    joxIn.close();
   } catch (Exception e) {
    e.printStackTrace();
   }
  }
   }
  
  
   /**
  * Returns an XML document.nbspString for the received bean
  */
   public static String toXML(Object bean) {
  ByteArrayOutputStream xmlData = new ByteArrayOutputStream();
  JOXBeanOutputStream joxOut = new JOXBeanOutputStream(xmlData);
  try {
   joxOut.writeObject(beanName(bean), bean);
   return xmlData.toString();
  } catch (IOException exc) {
   exc.printStackTrace();
   return null;
  } finally {
   try {
    xmlData.close();
    joxOut.close();
   } catch (Exception e) {
    e.printStackTrace();
   }
  }
   }
  
   /**
  * Find out the bean class name
  */
   private static String beanName(Object bean) {
  String fullClassName = bean.getClass().getName();
  String classNameTemp = fullClassName.substring(
    fullClassName.lastIndexOf(".") + 1,
    fullClassName.length()
    );
  return classNameTemp.substring(0, 1)
     + classNameTemp.substring(1);
   }
  }
  
  BeanXMLMapping类提供了两个方法来实现从JavaBean到XML文件的相互转换:
  toXML(): 产生bean实例相应的XML格式字符串
  fromXML(): 用XML格式的字符串创建bean实例
  
  组件的使用  列表2展示名为AccountHistoryContext的JavaBean,该类中的toXML()和fromXML()方法只是简单的调用BeanXMLMapping组件的toXML()和fromXML()方法。
  
  列表2 AccountHistoryContext bean
  public class AccountHistoryContext{
   private String dateFrom;
   public String getDateFrom() { return dateFrom; }
   public void setDateFrom(String s) { dateFrom = s; }
   ...
   // Other attributes with their get and set methods
  
   public String toXML()  {
  return BeanXMLMapping.toXML(this);
   }
   public static AccountHistoryContext fromXML (String xml)  {
   return (AccountHistoryContext) 
    BeanXMLMapping.fromXML (
      xml, AccountHistoryContext.class);
   }
  }
  
  图1显示一般的JavaBean类和其对应XML文件的映射关系
  
 如何轻松实现JavaBeans到XML的相互转换(图一)

  
  从JavaBean转换到XML
  XML文件的第一行是XML版本的申明,在上例中指定为1.0版(<?xml version="1.0" encoding="ISO-8859-1"?>)。
  下面一行定义XML文件的根接点,例子中为JavaBean的类名(<Bean>)。
  
  再下面就是定义跟节点的子节点。节点名为bean中通过get方法可以访问的属性。如果属性为基本类型(比如String,int),就直接用属性的名字生成节点。如果属性是另一个bean,则产生相应的嵌套节点.
  
  图2 显示ContactInfo类实例,ContactInfo类及由toXML()方法产生的XML文件。
  
 如何轻松实现JavaBeans到XML的相互转换(图二)

  
  从XML转换到JavaBean
  读XML文件时,根结点名,节点属性,嵌套节点会分别与bean,set方法和嵌套的beans建立映射关系。因此,要完成映射,必须为每个bean提供默认构造函数及每个属性的set方法(基本类型或嵌套bean)。
  
  图3 显示ContactInfo的XML文件,对应的ContactInfo类及通过fromXML()方法产生的ContactInfo类实例。
  
 如何轻松实现JavaBeans到XML的相互转换(图三)

  
  使用举例
  让我们看一个使用BeanXMLMapping组件的例子。例子由XML文件,JavaBean类和一个在线银行的快照组成。你可以从这里下载例子的源码.
  
  图4 在线银行的历史帐务页面。
  
 如何轻松实现JavaBeans到XML的相互转换(图四)

  图5显示类AccountHistory的类图, 列表3显示该类通过toXML()方法产生的XML文件。
  
 如何轻松实现JavaBeans到XML的相互转换(图五)

  列表3 XML封装的历史帐务信息
  <?xml version="1.0" encoding="ISO-8859-1"?>
  <AccountHistory>
   <transactionList>
  <transaction>
   <deposit></deposit>
   <withdraw>-$1,150.00 </withdraw>
   <date>3/10/2002 </date>
   <description>Check Number: 213 </description>
   <balance>$3,340.50</balance>
  </transaction>
  <transaction>
   <deposit></deposit>
   <withdraw>-$151.50</withdraw>
   <date>3/7/2002</date>
   <description>ATM Withdrawal 350 SAN JOSE CA</description>
   <balance>$3,189.00</balance>
  </transaction>
  <transaction>
   <deposit>$4,060.40 </deposit>
   <withdraw></withdraw>
   <date>3/5/2002</date>
   <description>ACH DEPOSIT - MyCompany </description>
   <balance>$7,249.40</balance>
  </transaction>
  <transaction>
   <deposit></deposit>
   <withdraw>-$20.00</withdraw>
   <date>2/26/2002</date>
   <description>JC'S BBQ AND DELI SAN JOSE CA </description>
   <balance>$7,229.40</balance>
  </transaction>
   </transactionList>
   <accountHistoryContext>
  <account>
   <holder>Paulo Caroli</holder>
   <type>checkings</type>
   <number>316614-10</number>
  </account>
  <dateTo>Monday, March 11, 2002 </dateTo>
  <dateFrom>Monday, February 25, 2002 </dateFrom>
   </accountHistoryContext>
  </AccountHistory>
  
  图6 时序图显示怎样找到类AccountHistory并调用其toXML()方法。
  
 如何轻松实现JavaBeans到XML的相互转换(图六)

  图7在线银行请求历史帐务的页面。帐号和日期显示在该页面上;列表4用XML封装该显示信息。
  
如何轻松实现JavaBeans到XML的相互转换(图七)

  列表4 XML封装的历史帐务请求信息
  <?xml version

原文转自:http://www.ltesting.net