如果你对Apache Cocoon有了解或者以涉足,你可能对在Cocoon中如何使用Java更好的实现特定的逻辑有所疑惑。这篇文章将给您介绍如何使用XSP(Extensible Server Page)和Action。同时还有示例和设计原则。
你可能听到了一些来自Apache的关于Cocoon的声音。现在,在经历了三年的发展后,Cocoon已经逐渐的从一个简单的实现XSL (Extensible Stylesheet Language) 转换的servlet成长为一个饱满的Web应用框架。
Cocoon是用Java开发的,一般做为servlet运行在象Tomcat这样的servlet容器中。
在这篇文章里,我们将介绍到两种办法来在基于Cocoon的应用中使用Java实现商业逻辑。
首先,让我们来总的了解一下Cocoon。
Cocoon正式的定义是一个XML发布引擎,我们可以理解Cocoon为一个用来产生、转换、处理和输出数据的框架。也可以理解Cocoon是一个从多种数据源接收数据再应用不同的处理,最后将数据以想要的格式输出的机器。
我们也可以定义Cocoon是一个数据流机器。也就是说,当你使用Cocoon时,你定义数据的路径或者流程来产生Web应用的页面。
下面是Cocoon主要的一些基本的原理:
1、Cocoon把所有的数据做为SAX (Simple API for XML) 事件来处理,任何非XML的数据都要转变成XML描述。
2、生成器(能生成SAX事件)的组件负责处理输入数据
3、序列化器负责处理输出数据,将数据输出到客户端(浏览器、文件等)。
4、开发人员组合生成器、序列化器和其它组件构成管道。所有的管道都在一个叫做站点地图的文件中定义。
5、通过URI (Uniform Resource Identifier)来匹配管道,但URI是与物理资源脱离的。
第5点需要说明一下:
对于传统的Web server,URI一般映射到物理资源。
例如,这个URI http://localhost/index.html 在Apache server将映射到一个叫index.html的HTML文件。
在Cocoon中,URIs 和 物理资源可以是没有任何绝对的相互关系的。你可以自由的设计URI来帮助用户更好的浏览你的站点。最后,你可以更好的组织你的文件让其容易管理和维护。
为了更好的了解Cocoon的处理模型,可以看一个简单的管道。
下面这个例子定义了一个叫index.html的页面。这个管道位于叫sitemap.xmap站点地图中:
<map:match pattern="index.html">
<map:generate type="file" src="content/mainfile.xml"/>
<map:transform type="xslt" src="content/stylesheets/mainstyle.xsl"/>
<map:serialize type="html"/>
</map:match>
这个管道有三步:
首先是一个生成器组件FileGenerator从XML文件"content/mainfile.xml "读取数据。
(FileGenerator实际上已经提前在地图中定义,可以通过"type"属性来引用。Cocoon中所有的管道组件都是通过它们的type属性来引用的。)
接着进行转换,转换器TraxTransformer将XSL stylesheet应用到引入的数据。
最后,序列化器HTMLSerializer将数据写到客户端的浏览器。
你可能疑惑,上面所说的和Java开发有什么联系呢?
我们把Cocoon的应用分成三个部分:
1、数据的收集层 Data Collection (Generation)
2、数据的处理和转换层 Data Processing&Transforming
3、数据的输出层 Data Output(Serialization)
那么,Java开发在Cocoon的处理转换层是非常重要的。Cocoon的转换和处理层是基于Cocoon的应用的核心,通过这一层对输入数据的处理,逻辑的应用,你就可以得到所期望的输出。
在Cocoon中,你可以有下面四种实现逻辑的方法:
1、使用转换器(Transformer)组件:他们按照你给定的规则转换传入的数据。典型的例子便是TraxTransformer。
2、通过不同的 request、session、URI来选择不同的组件做出正确的处理。
3、使用已有的或者自己实现的Action。
4、使用混合了Java代码和内容的XSP。
这篇文章介绍最后两种办法:XSP 和 Action。XSP 和 Action的开发都是在servlet context内。确切的说,两种组件(实际上是所有的组件)都要存取request, response, session, 和context对象。在某些方面,你要实现的大量的逻辑都会与这些对象相互作用。
XSP
XSP是Cocoon项目的创新。你可以把它和JSP相比较,因为它们都是混合逻辑和内容而且JSP的taglib和XSP的logicsheet也很相似。
XSP位于管道的起点,实际上它被Cocoon转换成生成器(Generator)来给管道中其余的组件提供数据。
让我们看下面这个叫 sample1.xsp 简单的示例:
<?xml version="1.0"?>
<xsp:page language="java" xmlns:xsp="http://apache.org/xsp">
<xsp:logic>
Date now = new Date();
String msg = "Boo!";
</xsp:logic>
<content>
<title>Welcome to Cocoon</title>
<paragraph>
This is an XSP. You can see how we it contain both logic
(inside the <xsp:logic> tags) and content. In the logic block above, we created a Date object whose value is <xsp:expr>now</xsp:expr>.
Oh, we also had a special message for you: <xsp:expr>msg</xsp:expr>
</paragraph>
</content>
</xsp:page>
首先注意这个文档的根标记是<xsp:page>。
<xsp:page language="java" xmlns:xsp="http://apache.org/xsp">
这个标记定义XSP的language(可以是Java或者JavaScript)和用到的逻辑单的namespace。
接着是我们定义了两个Java变量的<xsp:logic>块。
这些<xsp:logic>块可以有多个,可以出现在你希望的任何地方,而且可以包含各种Java代码。
最后,是我们自己的内容,从用户自己的跟标签开始,在上面的示例中是<content>。在内容部分里,我们可以用<xsp:expr>这个标签得到在前面定义的变量。
记住,一个XSP实际上就是一个生成器Generator。Cocoon将其转换成Java源文件然后编译、执行它。(如果想看XSP转换成的Java源文件,到你的servlet容器的工作路径下去找。例如,如果你使用Tomcat 4.0.4,那么路径就是下面这样:$CATALINA_HOME/work/Standalone/localhost/cocoon/cocoon-files/org/apache/cocoon/www.)
XSP执行后产生的XML数据被传递给管道其余的组件。
看下面这个管道实例:
<map:pipeline match="*.xsp">
<map:generate type="serverpages" src="examples/{1}.xsp"/>
<map:serialize type="xml"/>
</map:pipeline>
这里,我们使用一个指定的生成器 ServerPagesGenerator,来处理我们简单的XSP。返回给客户端未加修饰的XML。
注意例子中使用了特别的 {1} 变量引用:它代替值在管道开始处的通配符指示的值。也就是说,如果我们在浏览器中打开我们的Web应用中的sample1.xsp,那么 {1}的值便是sample1。
记住,同多数Cocoon组件一样,XSP访问request, response, session, 和 context 对象。这些对象实际上是HttpServletRequest, HttpServletResponse, HttpSession, 和HttpServletContext的封装,Cocoon正式版本提供了大量的存取这些对象的方法。
XSP在从数据库读取数据的时候特别有用。
数据库数据自然地以行和列组织,所以数据库数据很容易转换到XML。然而,JDBC(Java Database Connectivity)没有适合地代码完成向XML的转换。
XSP可以让我们在读取数据时很容易,这要感谢ESQL 逻辑单。ESQL 逻辑单除了隐藏了详细的JDBC代码,还允许将行和列放入到特定的标签中。同时ESQL 逻辑单也可以执行嵌套查询和执行更新命令。
下面,我们举个XSP应用的例子:
假如我们想将一些Cocoon的资源(名称和URL)存储到数据库。
首先,我们定义存放资源的数据表,然后当用户通过关键字搜索时,我们使用XSP来找到相应的行,将数据显示给用户。
随后,我们构建一个表单来增加新的列。
表的定义和插入的数据如下面所示。我们这里使用的数据库是MySQL,如果您使用的是其它的数据库,要注意做相应的改动。这个例子中,必须要有配置好数据库连接池。
表结构如下:
use test;
create table Resources (
ResourceURL varchar(255) not null,
ResourceName varchar(64) not null
);
插入一些资源数据:
insert into Resources values
(′;http://xml.apache.org/cocoon′;, ′Cocoon Home Page′);
insert into Resources values
(′;http://www.galatea.com/flashguides/cocoon-tips-2.xml′;, ′Cocoon 2.0 Tips and Tricks′);
表建好后并且Cocoon也正确的配置过后,我们就可以写下面这个XSP例子:
<?xml version="1.0"?>
<xsp:page language="java"
xml