使用Velocity模板

Velocity是一种针对Java应用的易用的模板语言。Velocity模板中没有任何 Java代码,这使得它能够同时被非开发人员和开发人员轻松地理解。Velocity的用户手册上是这么说的:“Velocity将Java代码从Web 页面中分离出来,使用Web站点从长远看更容易维护,并且提供了一种可行的JavaServer Pages替代解决方案。”

除了JSP,Velocity可能是用于Web应用的最流行的模板语言。因此很可能你会想采用Velocity作为视图层技术开发基于Spring的应用。幸运地是,Spring支持将Velocity作为Spring MVC的视图层模板语言。

让我们通过基于Velocity重新实现Spring培训应用中的视图层来看一下如何在Spring MVC中使用Velocity。

9.1.1 定义Velocity视图

假设你已经选择使用Velocity而不是JSP来创建Spring培训应用的视图。你需要 使用Velocity模板编写的页面之一是显示可用课程列表的页面。程序清单 9.1 显示了courseList.vm,一个和courseList.jsp等价的用于显示课程列表的Velocity模板。

 程序清单9.1 基于Velocity的课程列表

<html>

<head>

<title>Course List</title>

</head>

<body>

<h2>COURSE LIST</h2>

<table width="600" border="1" cellspacing="1" cellpadding="1">

<tr bgcolor="#999999">

<td>Course ID</td>

<td>Name</td>

<td>Instructor</td>

<td>Start</td>

<td>End</td>

</tr>

#foreach($course in $courses)

<tr>

<td>

<a href="displayCourse.htm?id=${course.id}">

${course.id}

</a>

</td>

<td>${course.name}</td>

<td>${course.instructor.lastName}</td>

<td>${course.startDate}</td>

<td>${course.endDate}</td>

</tr>

#end // 在所有课程中循环

</table>

</body>

</html>

可能你首先注意到的是这个模板中没有任何模板标签。这是因为Velocity不是基于与 JSP类似的标签的,而是采用了它自己的语言——称为Velocity模板语言(VTL)——用于流程控制和其他指令。在courseList.vm 中,#foreach指令用于循环处理一个课程列表,显示每个课程的明细。除了这个Velocity和JSP的基本区别之外,你会发现Velocity的 表达式语言和JSP很相似。事实上,当JSP使用${}作为它自己的表达式语言时,它不过是模仿Velocity的做法而已。这个模板仅仅演示了很少一部 分你可以使用Velocity所做的事情。

如果想知道更多,可以访问Velocity位于http://jakarta.apache.org/velocity的主页。注意当完成模板之后,你需要配置Spring使它可以在MVC应用中使用Velocity模板作为视图。

9.1.2 配置Velocity引擎

首先需要配置的是Velocity引擎自己。要做到这点,可以通过以下方式在Spring配置文件中声明一个VelocityConfigurer Bean:

<bean id="velocityConfigurer" class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">

<property name="resourceLoaderPath">

<value>WEB-INF/velocity/</value>

</property>

</bean>

VelocityConfigurer负责在Spring中设置Velocity引擎。这 里,我们通过属性resourceLoaderPath告诉Velocity到哪里寻找它的模板。我们建议将模板放到WEB-INF的某个子目录下面,这 样可以保证这些模板不能被直接访问。也可以通过velocityProperties属性来设置其他Velocity的配置细节。例如下面的 VelocityConfigurer配置:

<bean id="velocityConfigurer" class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">

<property name="resourceLoaderPath">

<value>WEB-INF/velocity/</value>

</property>

<property name="velocityProperties">

<props>

<prop key="directive.foreach.counter.name">loopCounter</prop>

<prop key="directive.foreach.counter.initial.value">0</prop>

</props>

</property>

</bean>

可以注意到velocityProperties属性使用一个<props>元 素来设置多个属性。在这里可以设置的属性与一个典型的Velocity应用中通过“velocity.properties”文件设置的属性是一样的。缺 省地,Velocity的#foreach循环维护一个名为$velocityCount的循环计数器,该计数器在第一轮循环开始时从1开始计数。但这里 我们设置属性directive.foreach.counter.name为loopCounter,因此将使用$loopCounter来引用循环计 数器。我们也通过设置属性directive.foreach.counter.initial.value为0使循环计数器由零开始计数。(想知道关于 Velocity配置属性的信息,请参考Velocity开发者指南http://jakarta.apache.org/velocity/developer-guide.html。)

9.1.3 解析Velocity视图

要使用Velocity模板视图,你必须做的最后一件事情是配置一个视图解析器。具体地说,需要以如下方式在Spring上下文配置中声明一个VelocityViewResolver Bean:

<bean id="viewResolver" class="org.springframework.

web.servlet.view.velocity.VelocityViewResolver">

<property name="suffix"><value>.vm</value></property>

</bean>

VelocityViewResolver和Velocity的关系与 InternalResourceViewResolver和JSP的关系相似。正如InternalResourceViewResolver,它使用 prefix属性和suffix属性由视图的逻辑名构造出模板文件的路径。这里我们仅仅设置suffix属性为“.vm”扩展名。由于模板目录的路径已经 通过VelocityConfigurer的resourceLoaderPath属性配置好了,因此这里不需要设置前缀。

注意:这里把Bean的ID设置为viewResolver。这一点很重要,因为我们并没有 配置DispatcherServlet检测所有的视图解析器。如果要同时使用多个视图解析器,则你很可能需要将这个ID改成某个更合适的名字(并且是惟 一的),比如velocityViewResolver。

现在,你的应用系统已经可以渲染基于Velocity模板的视图了。你只需要在返回的ModelAndView对象中通过逻辑名引用所需的视图。以ListCourseController为例,不需要做其他事情,因为它已经返回如下的ModelAndView对象:

return new ModelAndView("courseList", "courses", allCourses);

视图的逻辑名为“courseList”。当解析这个视图时,“courseList”加上后缀“.vm”构成了一个模板名“courseList.vm”。VelocityViewResolver会在WEB-INF/velocity路径下寻找这个模板。

至于“courses”模型对象,它会作为一个Velocity属性暴露给Velocity模板使用。在程序清单9.1中,它就是在#foreach指令中使用的集合对象。

9.1.4 格式化日期和数字

尽管应用已经配置成可以渲染Velocity视图了,但我们还有一些杂七杂八的问题需要解 决。当你比较程序清单9.1中的couseList.vm和courseList.jsp时,会注意到courseList.vm没有像 courseList.jsp一样对课程的ID、开始日期和结束日期进行格式化。在courseList.jsp中,课程ID显示为一个6位定长的前面以 零补齐的数字,而所有的日期以完整格式显示。为了完成courseList.vm,你需要对它作进一步的调整,对ID和日期属性进行格式化。

VTL并不直接支持日期和数字的格式化,而是通过提供日期和时间的工具类来支持格式化。为了 允许使用这些工具,你需要告诉VelocityViewResolver在模板中暴露它们时使用的属性名。这些属性名是通过 VelocityViewResolver的dateToolAttribute和numberToolAttribute属性来规定的:

<bean id="viewResolver" class="org.springframework.web.servlet.view.velocity.VelocityViewResolver">

<property name="dateToolAttribute">

<value>dateTool</value>

</property>

<property name="numberToolAttribute">

<value>numberTool</value>

</property>

</bean>

在这里,我们规定数字工具通过numberTool属性暴露给Velocity使用。因此,要格式化课程ID,你只需要通过数字工具的format()方法来处理课程ID即可,如下:

$numberTool.format("000000", course.id)

方法format()的第一个参数是模式字符串,在这里我们规定课程ID显示为6个数字的 域,必要时在前面补零。模式字符串的语法和java.text.DecimalFormat一致。请参考Velocity关于NumberTool的文档 来获取更多关于该工具功能的信息。

类似地,我们分配日期工具使用dateTool属性。为了格式化课程的开始和结束日期,只需使用日期工具的format()方法:

$dateTool.format("FULL", course.startDate)

$dateTool.format("FULL", course.endDate)

与数字工具的format()方法一样,第一个参数也是模式字符串。模式字符串的语法与 java.text.SimpleDateFormat一致。另外,也可以设置模式字符串为FULL、LONG、MEDIUM、SHORT或 DEFAULT中的一个,以使用标准的java.text.DateFormat模式。这里我们设置模式字符串为FULL来表示完整的日期格式。请参考 Velocity关于DateTool的文档来获得更多关于该工具功能的信息。

9.1.5 暴露请求和会话属性

尽管需要在Velocity模板中显示的大多数数据都可以通过ModelAndView对象的模型Map传递给视图,有时候也会需要显示servlet请求或会话中的属性。比如,当用户登录到应用系统时,用户的信息可能存放在servlet会话中。

如果在每一个控制器中都将请求或会话的属性复制到模型Map中,这会是非常笨拙的。幸运的 是,VelocityViewResolver会帮你将这些属性复制到模型中。属性exposeRequestAttributes和 exposeSessionAttributes告诉VelocityViewResolver是否需要将servlet请求和会话中的属性复制到模型 中。比如:

<bean id="viewResolver" class="org.springframework.web.servlet.view.velocity.VelocityViewResolver">

<property name="exposeRequestAttributes">

<value>true</value>

</property>

<property name="exposeSessionAttributes">

<value>true</value>

</property>

</bean>

这两个属性的默认值都为false。但在这里我们把这两个属性都设置为true,从而请求和会话的属性都会被复制到模型中,并且在Velocity模板中可见。

9.1.6 在Velocity中绑定表单域

在第8章中,我们看到如何使用Spring的<spring:bind>JSP标签将表单域绑定到一个命令对象中。这个标签在向用户显示表单域相关的错误时也是非常有用的。

幸运的是,当你使用Velocity而不是JSP时,不必放弃<spring:bind>提供的功能。Spring提供了若干个Velocity宏来模仿<spring:bind>标签的功能。

例如,假设Spring培训应用的学生注册表单是用Velocity模板编写的。程序清单9.2显示了registerStudent.vm中的一段,演示如何使用#springBind宏:

 程序清单9.2 在Velocity模板中使用#springBind

#springBind("command.phone")

phone: <input type="text"

name="${status.expression}"

value="http://www.blog.edu.cn/$!status.value">

<font color="#FF0000">${status.errorMessage}</font><br>

#springBind("command.email")

email: <input type="text"

name="${status.expression}"

value="http://www.blog.edu.cn/$!status.value">

<font color="#FF0000">${status.errorMessage}</font><br>

#springBind宏的参数是被绑定表单域的引用路径。它在模板中设置了一个名为status的变量用于保存表单域的名称、值以及可能出现的任何错误信息(可能来自一个验证器)。

如果错误信息中包含在HTML中有特殊意义的字符(比如:<,>,&),你可能需要对错误信息进行转义以正确显示在Web浏览器中。在这种情况下,你需要使用宏#springBindEscaped而不是#springBind:

#springBindEscaped("command.email", true)

除了域的引用路径之外,#springBindEscaped宏接受一个boolean参 数,表明是否需要对错误信息中的HTML特殊字符进行转义。如果该参数为false,则宏#springBindEscaped和#springBind 的行为完全一样,HTML特殊字符不会被转义。

为了在模板中使用Spring的宏,你需要通过VelocityViewResolver的exposeSpringMacroHelpers来使用这些宏:

<bean id="viewResolver" class="org.springframework.web.servlet.view.velocity.VelocityViewResolver">

<property name="exposeSpringMacroHelpers">

<value>true</value>

</property>

</bean>

通过把exposeSpringMacroHelpers属性设为true,你就能在Velocity模板中使用#springBind和#springBindEscaped宏。

尽管Velocity是一种广泛使用的JSP的替代技术,它不是惟一可以使用的替代模板技术。FreeMarker是另一种广为人知的用于在MVC应用的视图层中替代JSP的模板语

Spring中使用Velocity模板的更多相关文章

  1. SpringBoot 项目中使用velocity模板(转载)

    (不要使用这种模板了,spring boot最新版已经不支持了.使用FreeMarker吧:http://blog.csdn.net/clementad/article/details/5194262 ...

  2. spring boot 使用velocity模板(十六)

    (不要使用这种模板了,spring boot最新版已经不支持了.使用FreeMarker吧:http://blog.csdn.net/clementad/article/details/5194262 ...

  3. spring框架总结(04)----介绍的是Spring中的JDBC模板

    1.1  Jdbc模板概述 它是spring框架中提供的一个对象,是对原始Jdbc API对象的简单封装.spring框架为我们提供了很多的操作模板类,入下图所示: 我们今天的主角在spring-jd ...

  4. Spring中的JDBC模板类入门

    1.Spring框架中提供了很多持久层的模板类来简化编程,使用模板类编写程序会变的简单 2.提供了JDBC模板,Spring框架提供的 *JdbcTemplate类 3.Spring框架可以整合Hib ...

  5. Velocity初探小结--Velocity在spring中的配置和使用

    最近正在做的项目前端使用了Velocity进行View层的数据渲染,之前没有接触过,草草过了一遍,就上手开始写,现在又回头细致的看了一遍,做个笔记. velocity是一种基于java的模板引擎技术, ...

  6. 使用 Velocity 模板引擎快速生成代码(zhuan)

    http://www.ibm.com/developerworks/cn/java/j-lo-velocity1/ ****************************************** ...

  7. 【转载】Velocity模板引擎的介绍和基本的模板语言语法使用

    原文地址http://www.itzhai.com/the-introduction-of-the-velocity-template-engine-template-language-syntax- ...

  8. velocity模板引擎学习(4)-在standalone的java application中使用velocity及velocity-tools

    通常velocity是配合spring mvc之类的框架在web中使用,但velocity本身其实对运行环境没有过多的限制,在单独的java application中也可以独立使用,下面演示了利用ve ...

  9. java 利用spring JavaMailSenderImpl发送邮件,支持普通文本、附件、html、velocity模板

    java 利用spring JavaMailSenderImpl发送邮件,支持普通文本.附件.html.velocity模板 博客分类: Java Spring   本文主要介绍利用JavaMailS ...

随机推荐

  1. 瀑布流下滑 发送ajax

    <!DOCTYPE=html>      <html>      <head>      <meta charset="UTF-8"> ...

  2. 数据结构之最小生成树Prim算法

    普里姆算法介绍 普里姆(Prim)算法,是用来求加权连通图的最小生成树算法 基本思想:对于图G而言,V是所有顶点的集合:现在,设置两个新的集合U和T,其中U用于存放G的最小生成树中的顶点,T存放G的最 ...

  3. bzoj 3124 直径

    Written with StackEdit. Description 小\(Q\)最近学习了一些图论知识.根据课本,有如下定义. 树:无回路且连通的无向图,每条边都有正整数的权值来表示其长度.如果一 ...

  4. netcat 瑞士军刀

    netcat被誉为网络安全界的‘瑞士军刀’,一个简单而有用的工具,透过使用TCP或UDP协议的网络连接去读写数据.它被设计成一个稳定的后门工具,能够直接由其它程序和脚本轻松驱动.同时,它也是一个功能强 ...

  5. 51nod 1012 最小公倍数LCM

    输入2个正整数A,B,求A与B的最小公倍数. 收起   输入 2个数A,B,中间用空格隔开.(1<= A,B <= 10^9) 输出 输出A与B的最小公倍数. 输入样例 30 105 输出 ...

  6. Java JDK安装和配置(Windows)

    安装和配置JDK JDK中自带了JRE,不需要单独下载, 打开JDK安装, 选择安装目录,下一步,装完JDK,会问是否安装JRE,选下一步, 最后还会问是否安装Java FX, 装完后就全部完成了JD ...

  7. hexo搭建个人主页托管于github

    之前学习了 如何利用Github免费搭建个人主页,今天利用hexo来快速生成个人网页托管于github上. hexo系列教程:(一)hexo介绍 什么是hexo hexo是一个基于Node.js的静态 ...

  8. 《Troubleshooting SQL Server》读书笔记-内存管理

    自调整的数据库引擎(Self-tuning Database Engine) 长期以来,微软都致力于自调整(Self-Tuning)的SQL Server数据库引擎,用以降低产品的总拥有成本.从SQL ...

  9. SQL Server: Top 10 Secrets of a SQL Server Expert

    转载自:http://technet.microsoft.com/en-us/magazine/gg299551.aspx Many companies have downsized their IT ...

  10. HTML`CSS_网站页面不同浏览器兼容性问题解决

    目前,最为流行的浏览器共有五个:分别是ie,Edge浏览器(属于微软),火狐,谷歌(chrome)Safari和Opera五大浏览器. Trident内核:IE ,360,,猎豹,百度: Gecko内 ...