[翻译]使用 Velocity 构建一个web应用

为什么80%的码农都做不了架构师?>>>   hot3.png

作为JSP的替代方案,Velocity 经常被用来在应用中生成web页面。使用Velocity生成页面的一些好处有:

Simplicity - 页面可以被非技术型的web设计师创作和维护了。

Ease of maintainance – 脚本代码可以像MVC模式所要求的那样从web页面中移除了。

Access both methods and properties - web设计师可以在一个Context中引用方法和属性对象了。

Consistency - Velocity能够被用来执行其他类型的文本生成任务(比如发送邮件),从而提供一种一致的文本信息格式配置。

本文档提供一些关于在web应用中使用Velocity的入门信息。

 

使用一个框架

原始的使用Velocity引擎的目标是根据模板生成文本。所以Velocity中本身并没有包含任何和web相关的功能。为了让一个web应用起作用,你需要一个框架去回应HTTP请求、控制用户认证、调用业务逻辑,然后生成响应。下面是一些强大的竞争者。

1、Velocity Tools / VelocityViewServlet - 入门最简单的办法是下载相关 Velocity Tools 子项目,使用里面的VelocityViewServlet。 配置和安装这个servlet是容易的。在你的web服务器上面创建一个放模板文件的文件夹,选择性的XML文件,里面列出需要放入Context中的各种“工具”,就行了。更多的详细内容可以在下面的教程中找到。

2、Velocity Tools / VelocityStruts - 你也许知道原生的,被设计用来满足JSP应用功能需求的Struts框架。Velocity 的 VelocityStruts 模块可以代替JSP,使用Velocity 作为模板语言。这样就可以让你使用Velocity设计页面的时候可以大量的利用Struts的基础设施。

3、Third party frameworks – 已经有许多的第三方框架被列在 PoweredByVelocity wiki页面中。其中, Spring 可能是最繁茂和知名的。 Apache Turbine 有许多的特性也很有用。 它被构建的时候把Velocity作为基础的页面语言,这没有什么好惊讶的,因为许多的Velocity的开发者都参与了它的构建。 更加简单的选择有 Click 和 Maverick 框架, 它们提供了简单的,同Velocity集成良好的控制器结构。

4、Build your own - 最后的一个选择是去构建你自己的框架。 创建一个dispatcher servlet, 从文件系统或者数据库中抽取模板,加入你的业务逻辑数据,然后把结果发送给用户。 在已有的框架基础上定制,常常可以让你更加的节约时间。一般情况下,你可以通过创建一个VelocityViewServlet的子类添加新的功能。

另外,你可能偶然引用了 VelocityServlet 类, 它从版本1.4版本就被包含在 Velocity Engine 模块中,现在不建议使用了。 VelociyServlet 不会再被维护了,我们强烈建议你使用Velocity Tools中的VelocityViewServlet类。

 

Web特有的问题

web应用上的Velocity有一些特有的问题。下面是就一些最常见的问题的简要讨论。

令人头痛的资源加载

Velocity 设置默认使用 FileResourceLoader。 在没有被部署在servlet引擎中这样还是蛮好的。一旦你需要构建一个web应用,并且把这个应用发行或者部署成一个war文件,FileResourceLoader 就会成为你最大的敌人。所以,我们明确的建议你不要在你的web应用中使用 FileResourceLoader 。

真的,任何其他外部实现的 ResourceLoader 都行, 但是其他由Velocity Engine发布的 ResourceLoader 都需要你把你的模板文件存储在除了标准的文件系统以外的某个地方(比如:classpath、数据局,或者远程服务器)。如果那样对你是适用的,那就很棒了!然而,我们也要指出这些并不适合所有人的开发周期中的需求。

FileResourceLoader 最简单的替代事实上是 VelocityTool 计划的一部分。 它是 WebAppResourceLoader。 这个ResourceLoader像FileResourceLoader一样起作用,但是它知道servlet context,允许你配置servelt根路径下的资源路径,而不是本地的文件系统。

如果你正在使用VelocityViewServlet, 它可以自动配置并且准备好使用WebAppResourceLoader了。 因此,如果你想改变配置的路径, 你需要做的只是在你的 velocity.properties 文件中加上下面这样一行:

webapp.resource.loader.path=/WEB-INF/mytemplates/

如果你需要设置使用你自己实现的WebAppResourceLoader, 你像下面这样做配置:

resource.loader=webapp
webapp.resource.loader.class=org.apache.velocity.tools.view.WebappResourceLoader
webapp.resource.loader.path=/WEB-INF/mytemplates/

在你自己的 VelocityEngine 初始化之前,你也可能需要把 ServletContext 放入你自己的 VelocityEngine 属性中。这样就可以让 WebAppResourceLoader 知道如何去寻找到模板文件。

myVelocityEngine.setApplicationAttribute("javax.servlet.ServletContext", servletContext);

 

不要改变对象的状态

Velocity 提供调用一个对象的任何方法的能力,就像一个对象引用那样。这在需要在页面中展示信息的时候是很有用的,但是如果调用方法使对象或者应用的状态发生了变化,将会是很危险的。

比如,下面这个方法安全的调用了一个list 的 size方法展示结果。

There are $users.size() currently logged in.

一个不安全的方法,在context中操作一个与财务页面相关的对象,使数据一年一年的计算。这个calculateNextYear 方法计算下一年的数据,访问一个内部的计数器。

2005 data: $table.data
$table.calculateNextYear()
2006 data: $table.data

这种方式的问题是这段代码不能在页面的多个部分被重复。你可能不会想要这样去做,但是在剪切和粘贴代码或者编写控制结构(比如 #if 或者 #foreach)的时候很容易遗忘这一点。

这里(强烈的)建议的实践是仅仅使用 Velocity 与在文本中插入信息的场景。对于获取信息而言,调用方法是很有用的。而一般通过在模板文件中调用一个方法去改变对象的状态却是一个坏主意,使用这种方式去改变应用的状态永远都是个坏主意。

如果你发现自己需要去改变对象的状态(就像上面那种情况),尝试在控制器模块中去提前计算好所有可能的值,然后把它们放入一个List或者Map数据结构中。所有对应用状态的改变都应该在控制器模块中做完。

需要提到相关的一点,你应该常常把一个List或者Set对象放入context环境中,而不是一个Iterator或者Emumeration对象。这样就运行这样的集合对象可以被多次使用,而不会改变其行为属性。

 

避免 HTML/XML 实体

所有用户输入的包含特殊的 HTML 或者 XML 实体(比如 < , > 或者)的文本,都应该在包含进web页面之前被避免掉。 这是必须的,以确保文本可见,同时防止危险的 cross-site scripting (XSS,一种安全隐患)。不像比如JSTL(the Java Standard Tag Language found in Java Server Page)那样,Velocity默认不会去避免这些引用。

然后(万幸的是),Velocity通过提供一个ReferenceInsertionEventHandler 对象——它可以在被插入页面之前改变应用的值——来提供这种能力。有点特别的是,你能够同坐在你的 velocity.properties 文件中配置匹配一个正则表达式(可选的方式)来避免所有的这种实体引用。下面的这个例子将避免掉任何以“msg”开头的应用中的HTML实体(e.g. $mgsText)。\

eventhandler.referenceinsertion.class = org.apache.velocity.app.event.implement.EscapeHtmlReference
eventhandler.escape.html.match = /msg.*/

并不是说其他种类的避免有时候可能被用到。比如,在样式表中 @ 字符是需要被避免掉的,在 Javascript 字符串中单引号是该被避免掉的。

 

确保应用的安全

由于一个web应用是运行在一个中央服务器中的,那样通常会有多个用户和机密的资源,因而需要注意确保这个web应用时安全的。大部分适用于web应用的安全原则都已经构建于Velocity了。一些特殊的问题(比如系统配置,大多是 cross-site scripting和方法的内调)已经被 Building Secure Application with Velocity 这篇文章中被写到了。一般情况下,你可能想要阻止模板设计人员去包含“危险”的反射相关的方法,这时可以制定SecureUberSpector对象去 get/set 属性,执行方法调用。

runtime.introspector.uberspect = org.apache.velocity.util.introspection.SecureUberspector

 

日志文件

一个小的要点(在一些情况下)是,不用任何跟日志相关的配置 , Velocity 在当前路径下创建了一个日志文件。当 Velocity 被使用于一个web应用中时,当前路径常常在于应用服务的启动之处。如果你在你的服务器文件系统随机的什么地方开始查看“velocity.log”文件, 那就去检查 Velocity 日志配置。这归因于使用了置于你 classpath 中时的 Avalon Log Kit。典型的是, Velocity 用于一个web应用中,除了web页面生成的情况(比如:为了发送邮件)。为了解决这个问题,那就移除掉任何classpath或者property配置文件中的标有”avalon-logkit“,以控制日志文件位置的配置。

 

教程

接下来是一个使用 VelocityViewServlet 构建一个简单的web app的简明教程。

这里建议你从源代码编译 VelocityViewServlet。这并不是实际使用 VelocityViewServlet 需要做的,我们这样建议是为了能看到源代码,然后去编译实例文件的这种情况。

如下操作的前置条件是 JDK 和 Apache Ant。

1、从下载页面下载 Velocity Tools 项目源代码(你需要的实例的源代码)。

2、构建Velocity Tools jar文件和”simple“实例,通过敲入:

ant example.simple

3、看一看”simple“实例的目录。你将会看到一个”index.vm“文件,这里是其中内容的摘录:



I'm a velocity template.

#if( $XHTML )
  #set( $br = "
" ) #else #set( $br = "
" ) #end $br $br Here we use a custom tool: $toytool.message $br $br Here we get the date from the DateTool: $date.medium

你可以复制任何新加的velocity文件到相同的这个目录中。 在 example/WEB-INF 中,你会看到一个”tools.xml”文件。它包含了一个自动引入到context环境中的“工具”列表。


    
    
    
    this is foo
    this is bar.
    
        
    
    
        
    

最后在web.xml文件中指定servlet的名字和toolbox.properties文件的位置。


  
    velocity
    org.apache.velocity.tools.view.VelocityViewServlet
  
  
    velocity
    *.vm
  
  
    index.vm
  

4、把这个目录复制到你Tomcat下的webapps目录中。你也可以复制simple.war文件,但是复制整个目录可以让你尝试变化。你可通过这个(或者类似的)URL访问你的simple单页webapp:

http://localhost:8080/simple/index.vm

5、尝试加入新的Velocity页面。这里你可以访问任何velocity页面,通过改变URL。 尝试改变整个tools.xml的或者创建属于你自己的工具。查阅 Velocity Tools 文档,“showcase”实例应用,和wiki,以获取更多大量的利用工具的信息。

 

----------------------------------------

这里是原文的地址:

http://velocity.apache.org/engine/releases/velocity-1.7/webapps.html

 

 

 

 

 

 

 

 

 

。。。

转载于:https://my.oschina.net/xuleo/blog/131391

你可能感兴趣的:([翻译]使用 Velocity 构建一个web应用)