Turbine实战(中)

类别:Java 点击:0 评论:0 推荐:
3 实战

通过上面的演练,我们知道了如何定制自己Turbine应用中的Layout、Navigation和Screen。本节将带领大家一起从头实现。

3.1 Velocity

在上面的演练中,我们一句java代码都没编写,连Web Server都没有重启,仅仅是修改了一些“.vm”文件,就实现了页面布局的调整、显示内容的变化等工作,而这样一切神奇魔法的幕后功臣就是:Velocity。

为了在我们的Web Application中使用Velocity,需要在TurbineResources.properties文件中做如下配置:

# 开启Velocity Service

services.VelocityService.classname=org.apache.turbine.services.velocity.TurbineVelocityService

services.VelocityService.template.extension=vm

services.VelocityService.default.page = VelocityPage

services.VelocityService.default.screen=VelocityScreen

services.VelocityService.default.layout = VelocityECSLayout

services.VelocityService.default.navigation=VelocityNavigation

services.VelocityService.default.error.screen = VelocityErrorScreen

services.VelocityService.default.layout.template = Default.vm

services.VelocityService.file.resource.loader.path = /templates/app,/templates/flux

上图中只包含了几个比较重要的配置项,完整的配置模板在TDK例程的WEB-INF/conf/目录下的“TurbineResources.template”文件中。一般情况下,按照模板内的默认值进行配置就可以了,自己只需要修改以下两个选项:

l        services.VelocityService.default.layout.template-默认Layout的模板名。

l        services.VelocityService.file.resource.loader.path-模板文件的存放路径。以“,”间隔,根目录为Web Application所在目录。

我们先在下面的叙述中穿插讲述Velocity的使用方法,然后将另起篇幅和大家一起详细分析Velocity的执行机制。

3.2 Loader

在《Turbine简述》中提到,Turbine Servlet通过各种Loader动态装载Turbine中的五个模块:Action、Page、Screen、Navigation、Layout。Turbine中的所有Loader均派生自GenericLoader。Turbine 2.2中,GenericLoader表现为一个继承自Hashtable的纯虚类:

GenericLoader中,唯一的一个虚方法就是exec()。在这里,Turbine使用了Adapter Pattern和Command Pattern将Loader和各个Module结合在了一起,以LoginUser Action为例:

在这里,Turbine Servlet只管调用ActionLoader的exec()方法,不需要知道Action的接口信息,接口的转换在ActionLoader.exec()内完成。ActionLoader担任了Adapter Pattern中Adapter的职责,将源接口(Action.doPerform())转换成了目标接口(GenericLoader.exec())。使用Adapter Pattern,使得Turbine中各个模块的添加变得更为简单,如果日后需要的话,随时可以添加Action、Layout之外的任何模块,而对现有代码几乎没有影响。(不过值得提醒的是,Turbine目前只是定义了这个Adapter Pattern的框架,在实际的代码中并没有很好地利用)

同时,ActionLoader只管调用Action中的doPerform()方法,不需要知道LoginUser的任何信息,也不用管LoginUser是怎样接受请求,更不用管LoginUser事务处理的具体细节。Turbine通过这种方式实现了Command Pattern。这样,通过继承Action类,Turbine Application的开发者可以很轻松的扩展自己的Action,实现自己的专有事务;并且,通过这种模式,开发者很容易将已有的两个或多个Action组合为一个请求序列,以简化调用代码,使得项目代码更加清晰整洁、易于维护(当然,为了实现这一点,还需要用到Component Pattern,本文就不再针对此问题进行展开了)。

类似于ActionLoader,其他模块也按照上面的方法进行协同工作。通过使用这样的设计模式,Turbine Application就能很轻松的扩展,为再开发带来非常大的便利。再通过与TurbineResources.prooerties资源文件的结合,使得Turbine Application的可扩展性非常之强;并且,如果需要给已存在Application打补丁的话,也将是非常轻松便利。

3.3 Modules

Turbine中几大Module的具体实现都基本相同,因此,下面的篇幅将针对各模块的重点进行讲解,其他模块的相同部分将会一笔代过。

3.3.1 Screen

Screen是Turbine中最重要的表述层元素。最终页面中的大部分HTML代码将在此处生成。

3.3.1.1 HelloWorld Screen

依照惯例,我们先来看基于Velocity的HelloWorld:

package com.yourcompany.app.modules.screens;

 

// Velocity Stuff

import org.apache.velocity.context.Context;

 

// Turbine Stuff

import org.apache.turbine.util.RunData;

import org.apache.turbine.modules.screens.VelocityScreen;

 

public class HelloWorld extends VelocityScreen

{

    public void doBuildTemplate( RunData data, Context context )

        throws Exception

    {

        // the context object has already been setup for you!

        context.put ("hello", "this is a test...");

    }

}

HelloWorld Screen的包名应与TurbineResources.properties中的“module.packages”设置一致,对于此例来说,“module.packages”应做如下配置:

module.packages= com. yourcompany. app.modules

Note:包名可以有多个,各个包名之间使用“,”进行分隔。

Okay,就像我们所看到的,我们甚至不用返回任何对象,仅需要在Velocity Context中填充一些数据就可以了!

接下来,我们需要为我们的HelloWorld Screen创建一个名为HelloWorld.vm的模板:

<p>

    <font color="red">

        $hello of the emergency broadcast station.

    </font>

</p>

你没看错,就这么简单!

还记得要将它放在哪里吗?没错,就是“TEMPLATES-PATH/screens/”下。

现在,通过下面这样的URL,就能访问我们的HelloWorld了:

http://www.server.com/servlet/TurbineServlet/template/HelloWorld.vm

3.3.1.2 魔法的后面

在我们看到的最终结果中,是一个完整(fully formed)的HTML页面,.vm文件中的$hello已经被“this is a test...”所取代。

Velocity究竟在幕后做了些什么呢?你也许会感到诧异。现在,就让我来为你揭开谜底:

l        首先,Turbine会查看是否存在HelloWorld这个java类,如果存在,就执行它[i]。这个java类负责给.vm文件中的$hello赋值。

l        然后,调用Velocity的模板引擎,来解释、执行HelloWorld.vm模板文件(例如,生成相应Layout、Navigation等)

l        最后,将执行结果返回给用户

可以看到,使用Velocity后,相比起Servlet,一个页面的生成已经变得非常简单,并且,完全可以由网页设计者(负责.vm文件的编写)和程序开发员(负责java类的编写)协同完成同一个项目而又不互相牵制。而且,在这个过程中生成的模板文件是非常容易管理和重用的[ii]。此时,如果对应到MVC模式的话:

l        M – java类

l        V – .vm文件(完全符合HTML格式)

l        C – Turbine

[i] Turbine首先将.vm文件名的第一个字母大写,再去classpath中查找是否有相应的类。例如,如果模版文件名为Normal.vm或normal.vm的话,Turbine就会去查找是否存在类名为Normal的这个类;同样,helloWorld.vm对应HelloWorld这个类,role_editor对应Role_editor这个类。

[ii] 可以从示例看出,Screen的模板完全没有包含、混杂任何与Layout、Navigation相关的内容,这使得它很容易以“插件”的形式载入到任何地方。

本文地址:http://com.8s8s.com/it/it17560.htm