velocity模板引擎学习(2)-velocity tools 2.0
使用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模板引擎学习(2)-velocity tools 2.0的更多相关文章
- velocity模板引擎学习(4)-在standalone的java application中使用velocity及velocity-tools
通常velocity是配合spring mvc之类的框架在web中使用,但velocity本身其实对运行环境没有过多的限制,在单独的java application中也可以独立使用,下面演示了利用ve ...
- velocity模板引擎学习(3)-异常处理
按上回继续,前面写过一篇Spring MVC下的异常处理.及Spring MVC下的ajax异常处理,今天看下换成velocity模板引擎后,如何处理异常页面: 一.404错误.500错误 <e ...
- velocity模板引擎学习(1)
velocity与freemaker.jstl并称为java web开发三大标签技术,而且velocity在codeplex上还有.net的移植版本NVelocity,(注:castle团队在gith ...
- 【转载】Velocity模板引擎的介绍和基本的模板语言语法使用
原文地址http://www.itzhai.com/the-introduction-of-the-velocity-template-engine-template-language-syntax- ...
- 使用 Velocity 模板引擎快速生成代码(zhuan)
http://www.ibm.com/developerworks/cn/java/j-lo-velocity1/ ****************************************** ...
- 使用Velocity 模板引擎快速生成代码
Velocity 模板引擎介绍 在现今的软件开发过程中,软件开发人员将更多的精力投入在了重复的相似劳动中.特别是在如今特别流行的MVC架构模式中,软件各个层次的功能更加独立,同时代码的相似度也更加高. ...
- Velocity模板引擎介绍
整理下Velocity使用方法,整理比较详细用例 1 Velocity基础语法 1.1 用户和开发人员参考文档 http://velocity.apache.org/engine/releases/v ...
- Velocity模板引擎语法
Velocity 模板引擎介绍 Velocity是一个基于java的模板引擎(template engine).它允许任何人仅仅简单的使用模板语言(template language)来引用由java ...
- Velocity模板引擎入门
类似于PHP中的Smarty,Velocity是一个基于Java的模板引擎(template engine).它允许任何人仅仅简单的使用模板语言(template language)来引用由java代 ...
随机推荐
- php底层运行原理
http://www.cnblogs.com/phphuaibei/archive/2011/09/13/2174927.html
- 6、软件配置工程师要阅读的书籍 - IT软件人员书籍系列文章
软件配置管理工程师的工作也是贯穿整个项目过程的.其主要针对项目中的各种文档.技术源码等等进行归档控制.一般的配置项比如需求说明书,概要设计,详细设计,测试文档,用户手册等,还有源代码管理,数据库文档文 ...
- Asp.net MVC的Model Binder工作流程以及扩展方法(2) - Binder Attribute
上篇文章中分析了Custom Binder的弊端: 由于Custom Binder是和具体的类型相关,比如指定类型A由我们的Custom Binder解析,那么导致系统运行中的所有Action的访问参 ...
- 更换mysql数据目录后出现ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2) 的解决办法
服务器上的mysql默认数据目录为/var/lib/mysql/,同时服务器的/空间不是很大,而近期又有大量的日志需要导入进行分析,时常搞得/的空间捉襟见肘,晚上一狠心就想把mysql的数据目录转移到 ...
- C#处理猜拳问题(非窗体)
//猜拳,5局3胜,要求使用公用变量. namespace 结构体复习_公用变量 { class Program {public int rz=0; public int dz = 0; public ...
- Oracle 常用SQL技巧(转)
1. SELECT子句中避免使用 “*”当你想在SELECT子句中列出所有的COLUMN时,使用动态SQL列引用 ‘*’ 是一个方便的方法.不幸的是,这是一个非常低效的方法. 实际上,ORACLE在解 ...
- iOS 读取相册二维码,兼容ios7(使用CIDetector 和 ZXingObjC)
ios从相册读取二维码,在ios8以上,苹果提供了自带的识别图片二维码的功能,这种方式效率最好,也是最推荐的,但是如果你的系统需要向下兼容ios7,就必须用其他方式. 这里我选择的是 ZXingObj ...
- WIN 下的超动态菜单(一)
WIN 下的超动态菜单(一)介绍 WIN 下的超动态菜单(二)用法 WIN 下的超动态菜单(三)代码 作者:黄山松,发表于博客园:http://www.cnblogs.com/tomview/ ...
- 用Android Studio 开发Android应用
目前AndroidStudio已经到了1.2版本了,我用了下,觉得还蛮好的,有些自动生成的资源,它会自动帮你管理.下面开始列一下,我的开发环境搭配.在开始前,你得有个VPN,可者代理.嗯.不然你下不了 ...
- web性能优化系列之网站瓶颈识别
最近,公司网站的的访问量日益增大,PV马上过百万了.前期网站一到访问高峰,马上会变得很卡甚至打不开,后来做了很多优化后现在访问比较顺畅了.经过此事明白了一个道理,在遇到这类问题要做到两点,第一要相信自 ...