IBM®
跳转到主要内容
    中国 [选择]    使用条款
 
 
Select a scope:Search for:    
    首页    产品    服务与解决方案     支持与下载    个性化服务    
跳转到主要内容

developerWorks 中国  >  Information Management | Web development  >

结合 WebWork 和 Struts 等流行 Web 框架和 DB2 pureXML 开发 Web 应用程序

developerWorks
文档选项

未显示需要 JavaScript 的文档选项


黄耀华, 软件工程师, IBM
魏茂乾, 软件工程师, IBM

2007 年 11 月 12 日

本文主要介绍 pureXML 如何与当前 Web 流行框架进行整合开发Web应用程序。XML 数据的爆炸式增长,以及访问此类数据的 Web 服务的增长,都关系到 XML 数据存储与 XML 在 Web 中的应用。DB2 V9.5 提供了对 pureXML 的支持,成功地解决了这两方面的问题。

简介

DB2 V9.5 pureXML 为管理 XML 数据提供了丰富的功能。同时为 Web 开发提供了新的思路。XSLT 是一种把 XML 文档转换成其他形式的文档的语言。将 XML 转换为 HTML,是目前 XSLT 最主要的功能之一。XSLT 的这些功能特性,给 pureXML 的开发带来很好的便利性,使 pureXML 能够出色的利用在 Web 开发中。





回页首


示例表和数据

在讨论 pureXML 与 Web 框架结合使用的过程中,我们使用了表 charge, 表只有一列,列名是 chargedoc,类型为 XML。chargedoc 列包含一个列出收费信息的 XML 文档。表结构如下:


清单 1. 示例表结构
                
create table charge (chargedoc xml);


清单 2. 表中数据示例
                
<root>
  <fee_info timeMark="Mon Sep 10 11:34:05 CST 2007">
    <feeId>1</feeId>
    <feeTime>2007-09-10</feeTime>
    <feeNum>1</feeNum>
    <feeAdd />
  </fee_info>
</root>





回页首


pureXML 在 Web 开发中的应用

本文旨在介绍一种新的开发思路,因此采用了两种典型的 Web 框架 Struts 和 WebWork 来阐述开发过程。读者实际上可以在本文的基础上触类旁通,举一反三。

我们先以 WebWork 应用框架来说明如何利用 pureXML 开发 Web 应用程序。

XML 数据的存储

  1. 在展示层来定义要存储为 XML 类型的数据输入界面:

清单 3. 数据输入界面定义
                
<tr>
  <td class="gridLabel">
    <div align="right">检查名称:</div>
  </td>
  <td class="gridLabel">
    <input name="feeName" type="text" size="20"/>
  </td>
</tr>
<tr>
  <td class="gridLabel">
    <div align="right">检查费用:</div>
  </td>
  <td class="gridLabel">
    <input name="feeCharge" type="text" size="20"/>
  </td>
</tr>
<tr>
  <td class="gridLabel">
    <div align="right">检查时间:</div>
  </td>
  <td class="gridLabel">
    <input name="feeTime" type="text" size="20"/>
  </td>
</tr>

从页面的展示可以看出,我们需要把检查名称,检查费用和检查时间这三项来存储为 XML 数据,在实际应用中我们根据实际情况来生成 XML 并存储,为此我们需要把这些前台数据在我们的控制层来得到并把它组成我们所需要的 XML 格式,为此我们控制层需要的操作做准备。

  1. 在控制层声明对应的变量:

清单 4. 变量声明
                
private String feeName;
private long feeCharge;
private Date feeTime;
public String getFeeName() {
  return feeName;
}
public void setFeeName(String feeName) {
  this.feeName = feeName;
}
public Date getFeeTime() {
  return feeTime;
}
public void setFeeTime(Date feeTime) {
  this.feeTime = feeTime;
} 
public long getFeeCharge () {
  return feeCharge;
}
public void setFeeCharge (long feeCharge) {
  this. feeCharge = feeCharge;
}

  1. 在业务逻辑层把从输入界面得到的数据组装成 XML 格式,其方法如下:

清单 5. 组装 XML
                
StringBuffer chargeXMLInfo=new StringBuffer();
chargeXMLInfo.append("<root><fee_info timeMark=\"").append(
  new Date().toString()).append("\">");
chargeXMLInfo.append("<feeName>").append(
this.getFeeName()).append("</feeName>");
java.text.SimpleDateFormat sdf = new 
java.text.SimpleDateFormat("yyyy-MM-dd");
chargeXMLInfo.append("<feeTime>").append(
sdf.format(this.getFeeTime())).append("</feeTime>");
chargeXMLInfo.append("<feeCharge>").append(
this.getFeeCharge()).append("</feeCharge>").append(
  "</fee_info></root>");

  1. 在数据操作层保存 XML 数据,其 SQL 书写格式如下:

清单 6. 保存 XML
                
String sql="insert into charge 
  values (XMLVALIDATE(XMLPARSE(
  DOCUMENT "+chargeXMLInfo.toString()+
  ")ACCORDING TO XMLSCHEMA ID PATIENTCHARGE))";

该条 SQL 在执行时需要根据事先注册的 schema 来进行验证,如果验证通过,该条语句执行成功,否则 DB2 就抛出错误,提示输入 XML 不合乎 Schema 的定义。

当然也可以不进行 schema 验证,此时的 SQL 如下:


清单 7. 不进行 schema 验证
                
String sql="insert into charge 
  values (XMLPARSE(DOCUMENT "+chargeXMLInfo.toString()+")))";

是否进行 schema 验证,根据开发这实际情况来确定。

pureXML 同样支持对 XML 的节点更新。


清单 8. 更新 XML 节点
                
String sql = 
  "update charge set chargedoc = 
  xmlquery('transform copy $new:=$i modify do 
  insert "+ chargeXMLInfo.toString()+" as last 
  into $new/root return $new' passing chargedoc as \"i\")";

该条 SQL 执行后会在原来 XML 节点的基础上增加一个新的节点。

至此,利用 pureXML 可以将通过 Web 浏览器传输过来的数据成功保存到数据库。后面我们将讨论如何把存入到数据库中的 XML 数据查询出来并在浏览器中把结果展现出来。





回页首


XML 数据在客户端的展现

要实现把数据库中 XML 数据展现到客户端,可以有多种方式,这里介绍以 XSLT 的方式,操作步骤如下:

设计 XSLT

pureXML 与 XSLT 技术的结合,为 XML 在 Web 表示层的展现提供了便利性。要利用 XSLT 使 XML 在 Web 层展现,我们需要根据 XML 数据格式来定义需要的 XSLT,把该文件保存名为 charge.xslt。


清单 9. XSLT
                
<?xml version='1.0'?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="html" encoding="UTF-8" indent="yes"/>
  <xsl:template match="/root">
    <table width="100%" border="1">
      <xsl:for-each select="/root/fee_info">
        <tr>
          <td>
            <xsl:value-of select="@timeMark" />
          </td>
          <td>
            <xsl:value-of select="feeName" />
          </td>
          <td>
            <xsl:value-of select="feeTime" />
          </td>
          <td>
            <xsl:value-of select="feeCharge" />
          </td>
        </tr>
      </xsl:for-each>
    </table>
  </xsl:template>
</xsl:stylesheet>

从数据库中取出 XML 数据

把要展示的 XML 信息从数据库中读出。取数据时,可以把 XML 类型的数据当成 String 类型来读取。

下面简要介绍两种 SQL 查询的写法:


清单 10. 普通 SQL 方式查询
                
Connection conn = null;
try {
  Class.forName(Messages.getString("com.ibm.db2.jcc.DB2Driver"));
  bconn = DriverManager.getConnection(
  Messages.getString("jdbc:db2://9.125.73.81:50000/emr"),
  Messages.getString("db2inst1"),
  Messages.getString("mypassword")); 
  String info = null;
  String sql = "SELECT * FROM charge fetch first 1 rows only”;
  PreparedStatement ps = conn.prepareStatement(sql);
  ResultSet rs = ps.executeQuery();
  While(rs.next())
  {
    info=rs.getString(1);
  }
}
catch (SQLException e) {
  e.printStackTrace();
}
finally{
conn.close();


清单 11. XQuery 查询
                
String sql = "xquery for $c in db2-fn:xmlcolumn("charge.chargedoc") return {$c}";

XML 数据转换

从数据库取得 XML 信息后,根据前面定义的 XSLT,把它转换成可以在 Web 展示的信息。


清单 12. XML 数据转换
                
String displayCharge=null;
InputStream is =null;
try{
  InputStream is = getClass().getResourceAsStream(charge.xslt);
  StreamSource stylesource = new StreamSource(is);
  TransformerFactory tFactory = TransformerFactory.newInstance();
  Transformer transformer = tFactory.newTransformer(stylesource);
  Source source = new StreamSource(new StringReader(info));
  Writer writer = new StringWriter();
  Result result = new StreamResult(writer);
  transformer.transform(source, result);
  displayCharge = writer.toString();
}
catch(Exception e){
  e.printStackTrace();
}
finally{
  is.close();
}
return displayCharge;

转换后,对象 displayCharge 即为我们所需要的数据。

DB2 pureXML 还提供了内置的转换函数 XSLTransform(),也可以利用它来完成转换功能:

当然,首先需要将 xslt 文件 charge.xslt 存入 DB2 数据库 ;


清单 13. 使用 XSL Tranform 函数
                
create table my_xslt(xslt_id integer, xsltdoc xml);
insert into my_xslt values(1,?);// 此处利用 JDBC 将 charge.xslt 插入到数据库中
select xsltransform(chargedoc, xsltdoc) from charge a,my_xslt b where b.id=1;

XML 数据的展示

在上面功能都实现了后,在页面的展示层就比较容易了。通过下面语句就可以实现了。


清单 14. 实现展示层
                
<ww:property value=" displayCharge" />

同样,pureXML 也可以应用于其它 Web 框架中,下面我们简要介绍下在 Struts 中的应用。

  1. 在展示层定义

清单 15. 在展示层定义
                
<tr>
  <td class="gridLabel">
    <div align="right">检查名称:</div>
  </td>
  <td class="gridLabel">
    <html:text property="feeName"></html:text>
  </td>
</tr>
<tr>
  <td class="gridLabel">
    <div align="right">检查费用:</div>
  </td>
  <td class="gridLabel">
    <html:text property="feeCharge"></html:text>
  </td>
</tr>
<tr>
  <td class="gridLabel">
    <div align="right">检查时间:</div>
  </td>
  <td class="gridLabel">
    <html:text property="feeTime"></html:text>
  </td>
</tr>

  1. 在 form 层定义

清单 16. 在 form 层定义
                
public class Fee extends ActionForm {
String feeName;
String feeCharge;
String feeTime;
public String getFeeCharge() {
  return feeCharge;
}
public void setFeeCharge(String feeCharge) {
  this.feeCharge = feeCharge;
}
public String getFeeName() {
  return feeName;
}
public void setFeeName(String feeName) {
  this.feeName = feeName;
}
public String getFeeTime() {
  return feeTime;
}
public void setFeeTime(String feeTime) {
  this.feeTime = feeTime;
}
}

  1. 在业务逻辑层的定义

清单 17. 在业务逻辑层的定义
                
FeeForm feeForm = (FeeForm) form;
StringBuffer chargeXMLInfo = new StringBuffer();
chargeXMLInfo.append("<root><fee_info timeMark=\"").append(
  new Date().toString()).append("\">");
chargeXMLInfo.append("<feeName>").append(
  feeForm.getFeeName()).append("</feeName>");
java.text.SimpleDateFormat sdf = new 
  java.text.SimpleDateFormat("yyyy-MM-dd");
chargeXMLInfo.append("<feeTime>").append(
  sdf.format(feeForm.getFeeTime())).append("</feeTime>");
chargeXMLInfo.append("<feeCharge>").append(
  feeForm.getFeeCharge()).append(
  "</feeCharge>").append("</fee_info></root>");

其余的操作与 WebWork 基本类似,本文就不再做详细介绍了。





回页首


总结

DB2 pureXML 的出现,为 XML 的存储和使用提供了很好的支撑。本文着重介绍了 pureXML 如何与当前 Web 流行框架结合使用并给出一种解决方案。从展示层输入数据,控制层生成 XML 数据,业务逻辑层存储数据,以及到从数据库取出数据,通过 XSLT 把 XML 格式数据进行转换,最后在展示层显示等提供一套具体的实现方法。



参考资料

学习

获得产品和技术
  • 下载 IBM 软件试用版,体验强大的 DB2®,Lotus®,Rational®,Tivoli® 和 WebSphere® 软件。


作者简介

黄耀华是 IBM 中国软件开发中心的软件工程师。


魏茂乾是 IBM 中国软件开发中心的软件工程师。




对本文的评价

太差! (1)
需提高 (2)
一般;尚可 (3)
好文章 (4)
真棒!(5)

建议?




回页首


IBM 公司保留在 developerWorks 网站上发表的内容的著作权。未经IBM公司或原始作者的书面明确许可,请勿转载。如果您希望转载,请通过 提交转载请求表单 联系我们的编辑团队。
    关于 IBM 隐私条约 联系 IBM 使用条款