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代 ...
随机推荐
- Android Build Error(1)
Type 1 —— Build Path Problem : **.jar包文件缺失 1.在Android项目根目录下新建一个libs文件夹: 2.把你需要的导入的第三方Jar包复制进这个目录: 3. ...
- 为什么Java中字符串是不可变的
前言 在Java中,字符串是一个不可变的类,一个不可变的类指的是它的实例对象不能被修改,所有关于这个对象的信息在这个对象被创建时已初始化且不能被改变. 不可变类有很多优势,这篇文章总结了字符串类之所以 ...
- 每日Scrum(6)
今天是小组正式冲刺的第六天,软件的各种结尾工作,还有一些模块就已经全部实现了: 遇到的问题主要是对于自己能力的担忧,以前总是想,如果自己努力,就会怎样成功,其实并不是那样,小小的距离就是很远的能力差距 ...
- 【真的是随笔】如何利用htaccess把网站流量引到一个页面上(站点维护页效果)
咕咕咕,好久没来博客园转悠了,最近(这个最近好长啊)一直没时间写博(事实上也不知道写点什么有逼格的东西),所以一直都在潜水,,,(此处省略n字) 好了切入正题,关于如何把网站的所有流量引向一个页面的方 ...
- 给现有MVC 项目添加 WebAPI
1. 增加一个WebApi Controller, VS 会自动添加相关的引用,主要有System.Web.Http,System.Web.Http.WebHost,System.Net.Http 2 ...
- apache 虚拟主机详细配置:http.conf配置详解
apache 虚拟主机详细配置:http.conf配置详解 Apache的配置文件http.conf参数含义详解 Apache的配置由httpd.conf文件配置,因此下面的配置指令都是在httpd. ...
- .NET序列化的一点技巧(附Demo)
阅读目录 介绍 详细 处理 结论 Demo下载 介绍 序列化是将对象状态转换为可保持或传输的形式的过程.序列化的补集是反序列化,后者将流转换为对象.这两个过程一起保证数据易于存储和传输. .NET F ...
- SQL Server调优系列进阶篇(查询优化器的运行方式)
前言 前面我们的几篇文章介绍了一系列关于运算符的基础介绍,以及各个运算符的优化方式和技巧.其中涵盖:查看执行计划的方式.几种数据集常用的连接方式.联合运算符方式.并行运算符等一系列的我们常见的运算符. ...
- db2服务端安装图解
一. 准备工作 1. db2服务端安装包,版本:10.1.2 二. 安装图解过程 1. 响应文件是一个包含安装和配置信息的纯英文文本文件.可无需任何用户交互进行db2的批量安装.非必须的. 2. 点击 ...
- rhel7端口开放和查询
开启端口 firewall-cmd --zone=public --add-port=80/tcp --permanent 命令含义: --zone #作用域 --add-port=80/tcp #添 ...