使用velocity后,原来的很多标签无法使用了,必须借助velocity tools来完成,目前velocity tools最新版本是2.0,下面是velocity tools的一些注意事项:

1. 与Spring MVC 3.x/4.x的集成问题

Spring 3.x/4.x只支持1.3.x的velocity tools,要使用2.0必须自己扩展VelocityToolboxView类

 package org.springframework.web.servlet.view.velocity;

 import java.util.Map;

 import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.apache.velocity.context.Context;
import org.apache.velocity.tools.Scope;
import org.apache.velocity.tools.ToolManager;
import org.apache.velocity.tools.view.ViewToolContext;
import org.springframework.web.servlet.view.velocity.VelocityToolboxView; public class VelocityToolbox2View extends VelocityToolboxView {
@Override
protected Context createVelocityContext(Map<String, Object> model,
HttpServletRequest request, HttpServletResponse response)
throws Exception {// Create a
// ChainedContext
// instance.
ViewToolContext ctx; ctx = new ViewToolContext(getVelocityEngine(), request, response,
getServletContext()); ctx.putAll(model); if (this.getToolboxConfigLocation() != null) {
ToolManager tm = new ToolManager();
tm.setVelocityEngine(getVelocityEngine());
tm.configure(getServletContext().getRealPath(
getToolboxConfigLocation()));
if (tm.getToolboxFactory().hasTools(Scope.REQUEST)) {
ctx.addToolbox(tm.getToolboxFactory().createToolbox(
Scope.REQUEST));
}
if (tm.getToolboxFactory().hasTools(Scope.APPLICATION)) {
ctx.addToolbox(tm.getToolboxFactory().createToolbox(
Scope.APPLICATION));
}
if (tm.getToolboxFactory().hasTools(Scope.SESSION)) {
ctx.addToolbox(tm.getToolboxFactory().createToolbox(
Scope.SESSION));
}
}
return ctx;
}
}

注:31行tm.configure(getServletContext().getRealPath(getToolboxConfigLocation()));这里,在某些容器,比如weblogic中,getRealPath可能取不到值,可改成

getResource试试

然后在spring mvc的servlet配置文件中参考如下设置:

 <bean
class="org.springframework.web.servlet.view.velocity.VelocityViewResolver">
<property name="order" value="0" />
<property name="cache" value="true" />
<property name="prefix" value="" />
<property name="suffix" value=".vm" />
<property name="toolboxConfigLocation" value="/WEB-INF/toolbox.xml" />
<property name="contentType" value="text/html;charset=UTF-8" />
<property name="viewClass" value="org.springframework.web.servlet.view.velocity.VelocityToolbox2View"></property>
</bean>

2. 如何获取当前应用的contextPath

     <tool>
<key>link</key>
<scope>request</scope>
<class>org.apache.velocity.tools.view.LinkTool</class>
</tool>

借助velocity-tools的LinkTool类,在velocity中直接用${link.contextPath}即可得到当前的contextPath

3、如何获取url参数

     <tool>
<key>params</key>
<scope>request</scope>
<class>org.apache.velocity.tools.view.ParameterTool</class>
</tool>

然后就可以用类似$params.returnUrl,来获取类似 http://xxx.com/login?returnUrl=abc 中的 abc部分

4、如何与Spring-Security集成

 <sec:authorize access="isAnonymous()">
...
</sec:authorize>

之类的标签无法在velocity中使用,而velocity-tools中也未提供相应的支持,在老外的一篇博客上,看到了解决方案:

 package com.cnblogs.yjmyzz.utils;

 import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails; public class VelocitySecurityUtil { public static String getPrincipal() { Object obj = SecurityContextHolder.getContext().getAuthentication()
.getPrincipal(); if (obj instanceof UserDetails) {
return ((UserDetails) obj).getUsername();
} else {
return "anonymous";
}
} public static boolean isAuthenticated() {
return !getPrincipal().equals("anonymous");
} public static boolean allGranted(String[] checkForAuths) {
Set<String> userAuths = getUserAuthorities();
for (String auth : checkForAuths) {
if (userAuths.contains(auth))
continue;
return false;
}
return true;
} public static boolean anyGranted(String[] checkForAuths) {
Set<String> userAuths = getUserAuthorities();
for (String auth : checkForAuths) {
if (userAuths.contains(auth))
return true;
}
return false;
} public static boolean noneGranted(String[] checkForAuths) {
Set<String> userAuths = getUserAuthorities();
for (String auth : checkForAuths) {
if (userAuths.contains(auth))
return false;
}
return true;
} private static Set<String> getUserAuthorities() {
Object obj = SecurityContextHolder.getContext().getAuthentication()
.getPrincipal();
Set<String> roles = new HashSet<String>();
if (obj instanceof UserDetails) {
@SuppressWarnings("unchecked")
Collection<GrantedAuthority> gas = (Collection<GrantedAuthority>) ((UserDetails) obj)
.getAuthorities();
for (GrantedAuthority ga : gas) {
roles.add(ga.getAuthority());
}
}
return roles;
} }

然后修改配置:

     <bean id="velocitySecurityUtil" class="com.cnblogs.yjmyzz.utils.VelocitySecurityUtil" />

     <bean
class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="order" value="1" />
...
<property name="viewResolvers">
<list>
<bean
class="org.springframework.web.servlet.view.velocity.VelocityViewResolver">
<property name="order" value="0" />
...
<property name="attributesMap">
<map>
<entry key="sec">
<ref bean="velocitySecurityUtil" />
</entry>
</map>
</property> </bean>
...

页面就能用了:

     #if(${sec.authenticated})
...
#end

注:这个思路也可以用于实现自己的Velocity-Tools类,比如我们创建了一个自己的RequestUtil类

 package com.cnblogs.yjmyzz.utils;
import javax.servlet.http.HttpServletRequest;
public class RequestUtil{ /**
* 获取当前请求的基地址(例如:http://localhost:8080/ctas/xxx.do 返回 http://localhost:8080/ctas/)
*
* @param request
* @return
*/
public static String getBaseUrl(HttpServletRequest request) {
return request.getRequestURL().substring(0,
request.getRequestURL().indexOf(request.getContextPath()) + request.getContextPath().length()) + "/";
} }

然后在配置里,加上

     <bean id="requestUtil" class="com.cnblogs.yjmyzz.utils.RequestUtil"/>

     <bean
class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="order" value="1"/>
...
<property name="viewResolvers">
<list>
...
<bean
class="org.springframework.web.servlet.view.velocity.VelocityViewResolver">
<property name="order" value="0"/>
...
<property name="viewClass"
value="com.cnblogs.yjmyzz.utils.VelocityToolbox2View"></property>
<property name="attributesMap">
<map>
...
<entry key="req">
<ref bean="requestUtil"/>
</entry>
</map>
</property>
</bean>
...
</bean>

vm页面这样用

 #*取得页面链接基地址*#
#macro(baseHref)${req.getBaseUrl($request)}#end
...
<base href="#{baseHref}">
...
<script type="text/javascript">
var baseHref = "#{baseHref}";
</script>
...

顺便提一句:网上有一堆文章和教程,让你在toolbox.xml中添加类似

     <tool>
<key>req</key>
<scope>request</scope>
<class>com.cnblogs.yjmyzz.utils.RequestUtil</class>
</tool>

在Spring MVC4 + Velocity Tools2的组合下,然而,这并没有什么用,在Spring MVC4 + Velocity-Tools2下,已经不好使了。

最后,Velocity还允许自定义标签(也有人称为自定义指令),支持开发人员定义自己的标签,比如#YourDirective,详情可参考:

编写自定义的 Velocity 指令

velocity模板引擎学习(2)-velocity tools 2.0的更多相关文章

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

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

  2. velocity模板引擎学习(3)-异常处理

    按上回继续,前面写过一篇Spring MVC下的异常处理.及Spring MVC下的ajax异常处理,今天看下换成velocity模板引擎后,如何处理异常页面: 一.404错误.500错误 <e ...

  3. velocity模板引擎学习(1)

    velocity与freemaker.jstl并称为java web开发三大标签技术,而且velocity在codeplex上还有.net的移植版本NVelocity,(注:castle团队在gith ...

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

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

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

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

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

    Velocity 模板引擎介绍 在现今的软件开发过程中,软件开发人员将更多的精力投入在了重复的相似劳动中.特别是在如今特别流行的MVC架构模式中,软件各个层次的功能更加独立,同时代码的相似度也更加高. ...

  7. Velocity模板引擎介绍

    整理下Velocity使用方法,整理比较详细用例 1 Velocity基础语法 1.1 用户和开发人员参考文档 http://velocity.apache.org/engine/releases/v ...

  8. Velocity模板引擎语法

    Velocity 模板引擎介绍 Velocity是一个基于java的模板引擎(template engine).它允许任何人仅仅简单的使用模板语言(template language)来引用由java ...

  9. Velocity模板引擎入门

    类似于PHP中的Smarty,Velocity是一个基于Java的模板引擎(template engine).它允许任何人仅仅简单的使用模板语言(template language)来引用由java代 ...

随机推荐

  1. Play Framework 完整实现一个APP(二)

    1.开发DataModel 在app\moders 下新建User.java package models; import java.util.*; import javax.persistence. ...

  2. ios app响应background,foreground 事件实现

    1 通过AppDelegate 实现 App进入后台事件方法 - (void)applicationDidEnterBackground:(UIApplication *)application AP ...

  3. sql server 小记——分区表(上)

    我们知道很多事情都存在一个分治的思想,同样的道理我们也可以用到数据表上,当一个表很大很大的时候,我们就会想到将表拆 分成很多小表,查询的时候就到各个小表去查,最后进行汇总返回给调用方来加速我们的查询速 ...

  4. Cloudera5.8.3:Flume+Morphline+Solr开发小技巧

    1.Flume和Morphline添加日志打印 log4j.logger.org.apache.flume.sink.solr=DEBUG log4j.logger.org.kitesdk.morph ...

  5. 数据分页处理系列之一:Oracle表数据分页检索SQL

      关于Oracle数据分页检索SQL语法,网络上比比皆是,花样繁多,本篇也是笔者本人在网络上搜寻的比较有代表性的语法,绝非本人原创,贴在这里,纯粹是为了让"数据分页专题系列"看起 ...

  6. my_strcat()

    char* my_strcat(char* S1,const char* S2){ //严格符合strcat()的接口形式,需要的S1空间是两个字符串空间总和-1. int i=0,j=0; whil ...

  7. docker-7 docker在阿里云的使用

    在传统模式中,开发团队在开发环境中完成软件开发,自己做了一遍单元测试, 测试通过,ᨀ交到代码版本管理库.运维把应用部署到测 试环境, QA 进行测试,没问题后通知部署人员发布到生产环境. 在上述过程中 ...

  8. Ubuntu13.04安装历险记--Mono,Nginx,Asp.Net一个都不能少

    ----Ubuntu13.04安装历险记--新人新手新作------------------------------------------------- 注:以下操作均省略权限获取操作,如有需要,请 ...

  9. MVC调用SVC无法找到资源解决问题

    webconfig配置下就可以,但MVC当中老是报错 404 not found.解决办法: routes.IgnoreRoute("{resource}.svc/{*pathInfo}&q ...

  10. flex sdk中mx_internal function getTextField() 这种函数如何调用?

    在用flex 开发中,一些函数前打上了 mx_internal 外部调用不了,其实这样写就可以了 xxx.mx_internal::getTextField() 而 xxx.getTextField( ...