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代 ...
随机推荐
- yii2发送邮件教程
作者:白狼 出处:http://www.manks.top/article/yii2_swiftMailer本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接, ...
- JavaScript Patterns 5.6 Static Members
Public Static Members // constructor var Gadget = function (price) { this.price = price; }; // a sta ...
- jquery中attr和prop的区别、 什么时候用 attr 什么时候用 prop (转自 芈老头 )
jquery中attr和prop的区别. 什么时候用 attr 什么时候用 prop 在高版本的jquery引入prop方法后,什么时候该用prop?什么时候用attr?它们两个之间有什么区别?这 ...
- Office——EXCEL 打开自动修改 关闭自动保存
==================================声明================================== 本文版权归作者所有 未经作者授权 请勿转载 保留法律追究的 ...
- Java api 入门教程 之 JAVA的Random类
在实际的项目开发过程中,经常需要产生一些随机数值,例如网站登录中的校验数字等,或者需要以一定的几率实现某种效果,例如游戏程序中的物品掉落等. 在Java API中,在java.util包中专门提供了一 ...
- Arch Linux sudo: PAM authentication error: Module is unknown [Solved!]
问题描述: 我的 Arch Linux 已经用了快半年多,由于 Arch Linux 的滚挂问题,我从没有直接升级过系统.软件版本以及库自然落后了一些. 就在我准备需要用到 NFS 时,挂载网络文件系 ...
- STM32学习笔记——USART串口
转载自:http://www.cnblogs.com/microxiami/p/3752715.html 一.USART简介 通用同步异步收发器(USART)提供了一种灵活的方法与使用工业标准NRZ异 ...
- nodejs模块——http模块
http模块主要用于创建http server服务. 本文还用到url模块和path模块,还有fs模块.url模块用于解析url,path模块用于处理和转换文件路径. 一.简单应用 代码如下: // ...
- Golang tips
1.go test 测试单个函数 go test -v -test.run Test* 2.
- NOIP2009靶形数独[DFS 优化]
描述 小城和小华都是热爱数学的好学生,最近,他们不约而同地迷上了数独游戏,好胜的他们想用数独来一比高低.但普通的数独对他们来说都过于简单了,于是他们向 Z博士请教,Z 博士拿出了他最近发明的“靶形数独 ...