velocity的使用

velocity是什么

Velocity应用于web开发时,界面设计人员可以和java程序开发人员同步开发一个遵循MVC架构的web站点,也就是说,页面设计人员可以只关注页面的显示效果,而由java程序开发人员关注业务逻辑编码。Velocity将java代码从web页面中分离出来,这样为web站点的长期维护提供了便利,同时也为我们在JSP和PHP之外又提供了一种可选的方案。

velocity的基本语法

说到Velocity基本语法,我觉得大家直接在百度里面搜索就可以了可以看一下点击打开链接等,这些语法主要是针对在 .vm文件中的语法,当然标签还是支持html标签的,只是说比如有时候我们用jstl的时候表达如果符合某项条件要执行什么的时候是<c:if test="${student.age==1}">you win</c:if> 但是在velocity中一般都是#if($!{student.age==1})you win #end 这样来表示,这就是jsp中语法和vm语法的区别之处,当然还有很多,就不一一举例,这边我主要是介绍怎么搭起和使用velocity和springmvc结合使用。

velocity结合springmvc快速上手使用

什么引用框架都是需要冲jar包开始,现在我们就从maven导包开始,那么我们需要引入什么包呢?
<!-- veocity模板引擎需要用到的文件包依赖 -->
		<dependency>
				<groupId>org.apache.velocity</groupId>
				<artifactId>velocity</artifactId>
				<version>1.7</version>
		</dependency>
		
		<dependency>
			<groupId>org.apache.velocity</groupId>
			<artifactId>velocity-tools</artifactId>
			<version>2.0</version>
			<exclusions>
				<exclusion>
					<groupId>org.apache.struts</groupId>
					<artifactId>struts-taglib</artifactId>
				</exclusion>
				<exclusion>
					<groupId>org.apache.struts</groupId>
					<artifactId>struts-tiles</artifactId>
				</exclusion>
				<exclusion>
					<groupId>org.apache.struts</groupId>
					<artifactId>struts-core</artifactId>
				</exclusion>
				<exclusion>
					<groupId>commons-validator</groupId>
					<artifactId>commons-validator</artifactId>
				</exclusion>
				<exclusion>
					<groupId>commons-logging</groupId>
					<artifactId>commons-logging</artifactId>
				</exclusion>
			</exclusions>
		</dependency>

		<!-- veocity模板引擎需要用到的文件包依赖 -->
接下来我们就要在springmvc-servlet.xml的配置贴出来,在稍微做一些解释
	<!-- 模板引擎的springmvc配置bean -->
	<bean id="velocityConfig" class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">
		<property name="resourceLoaderPath" value="/WEB-INF/velocity/" />
		<property name="velocityProperties">
			<props>
				<prop key="directive.foreach.counter.name">loopCounter</prop>
				<prop key="directive.foreach.counter.initial.value">0</prop>
				<prop key="input.encoding">utf-8</prop>
				<prop key="output.encoding">utf-8</prop>
				<prop key="velocimacro.library">macro/macro.vm</prop>
			</props>
		</property>
	</bean>


	<!-- 使用VelocityLayoutViewResolver就证明我们需要给它指定一个模板,并且指定模板放置的位置,所以一般如果你返回的界面上没有加#set($layout = "/layout/指定的模板.vm")都会使用默认的这个模板   -->
	<!-- 如果我们不想要支持Velocity的布局,我们这里就换成org.springframework.web.servlet.view.velocity.VelocityViewResolver -->
	<bean id="velocityView" class=" org.springframework.web.servlet.view.velocity.VelocityLayoutViewResolver">
		<property name="suffix" value=".vm" />
		<property name="exposeSpringMacroHelpers" value="true" />
		<property name="layoutUrl" value="layout/default.vm" />
		<property name="dateToolAttribute" value="dateTool" />
		<property name="contentType">
			<value>text/html;charset=UTF-8</value>
		</property>
		<property name="toolboxConfigLocation" value="WEB-INF/velocity-toolbox.xml" />
	</bean>
	<!-- 模板引擎的springmvc配置bean -->




   	<!-- 模板引擎关于静态资源填充到主模块的拦截器 -->
   	<mvc:interceptors>
		<bean class="com.yiyong.mavenspring.demo.helper.StaticResourceTool" />
	</mvc:interceptors>

 如果你配置过velocity,你会发现与你之前的配置主要有两个地方的差别:

    1.  一般情况下,当我们不使用velocity的布局功能时,我们一般会把viewResolver的class配置为:

org.springframework.web.servlet.view.velocity.VelocityViewResolver,当需要使用布局功能的时候,viewResolver的class需要配置为:

org.springframework.web.servlet.view.velocity.VelocityLayoutViewResolver,顾名思义,从命名中我们就能看出来这个viewResolver是支持layout功能的。

    2.  另外一点不同的是,这里多了一个layoutUrl的属性配置:<property name="layoutUrl" value="layout/layout.vm" />, 这个配置是设置你的layout文件的存在路径,需要注意的是,这个路径不是相对于webapp路径来的,而是相对于velocityConfig配置中的resourceLoaderPath属性配置的路径(resourceLoaderPath的路径是相对于webapp的路径)。


<prop key="velocimacro.library">macro/macro.vm</prop>这个的配置主要是结合<mvc:interceptors><bean class="com.yiyong.mavenspring.demo.helper.StaticResourceTool" /></mvc:interceptors>动态在模板中引入在子页面中需要用到的静态文件(css / js)。流程是这样的,请求过成可以看一下我上一篇的那个springmvc请求过成,当返回ModelAndView的时候,已经初始化了LocalThread中的csslist和jslist(在ThreadLocal类中有一个Map,用于存储每一个线程的变量副本,Map中元素的键为线程对象,而值对应线程的变量副本)。请求最后是返回ModelAndView在返回经过拦截器的时候就把StaticResourceTool实例对象引入,这样就可以利用velocimacro.library在modelandview自动提取。
还有一个就是toolbox.xml这个文件主要配置一些静态类,想日期转换工具类或者esc工具类等,在界面上可以直接$class.()直接得到想要的结果。
它的优势是可以避免引入不必要的静态文件,让每次引入的静态文件达到最简洁。
现在把macro.vm的代码贴出来:
#macro(importJavascript $script)
    $staticTool.importJavascript($script)
#end
#macro(importCss $css)
    $staticTool.importCss($css)
#end
#macro(printJavascript)
    #if($staticTool.javascriptFiles)
        #foreach($f in $staticTool.javascriptFiles)
            <script src="$f"></script>
        #end
    #end
#end
#macro(printCss)
    #if($staticTool.cssFiles)
        #foreach($css in $staticTool.cssFiles)
            <link href="$css" rel="stylesheet">
        #end
    #end
#end
#macro(jsBlock)
    $staticTool.appendJsBlock("$bodyContent")
#end
#macro(printJsBlock)
	#if($staticTool.jsBlock)
	<script>
    $!staticTool.jsBlock
    </script>
    #end
#end
同时也把静态引入静态文件的拦截器类也展示给大家:
package com.yiyong.mavenspring.demo.helper;




import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

/**
 * 
 * @author yiyong wu
 * @date 2015年12月13日 上午11:10:11
 *这狗工具类是结合velocity模板引擎来使用的 。在一个统一的界面上我们定义一些固定的样式静态文件和一些js文件。
 *但是当我们需要特有页面进行挑战的时候需要把这些静态文件带到固定界面的default.vm那边去,所以使用这个拦截器工具类
 */
public class StaticResourceTool implements HandlerInterceptor {

    private ThreadLocal<List<String>> importCss = new ThreadLocal<List<String>>();
    private ThreadLocal<List<String>> importJavascript = new ThreadLocal<List<String>>();
    private ThreadLocal<StringBuilder> jsBlock = new ThreadLocal<StringBuilder>();


    public StaticResourceTool() {

    }

    public void init() {

    }

    public void importJavascript(String uri) {
        importJavascript.get().add(uri);
    }

    public void importCss(String uri) {
        importCss.get().add(uri);
    }

    public void appendJsBlock(String string) {
        jsBlock.get().append(string);
    }



    public List<String> getJavascriptFiles() {
        return importJavascript.get();
    }

    public List<String> getCssFiles() {
        return importCss.get();
    }

    public String getJsBlock() {
        return jsBlock.get().toString();
    }



    public void clear() {
        importCss.remove();
        importJavascript.remove();
        jsBlock.remove();
    }

	public void afterCompletion(HttpServletRequest request,
			HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
			importCss.remove();
	        importJavascript.remove();
	}

	public void postHandle(HttpServletRequest request, HttpServletResponse response,
			Object handler, ModelAndView modelAndView) throws Exception {
		   if (modelAndView != null) {
	            modelAndView.addObject("staticTool", this);
	        }
		
	}

	public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
			Object handler) throws Exception {

        importCss.set(new ArrayList<String>());
        importJavascript.set(new ArrayList<String>());
        jsBlock.set(new StringBuilder());
        return true;
	}

}

这样我们就该进行到把默认的布局vm展示给大家的时候,layout.vm的布局结构如下
<!DOCTYPE html>
<html lang="en">

<head>

<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">

<title>Demo測試</title>

<!-- Bootstrap Core CSS -->
<link href="$request.contextPath/assets/lib/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet">

<!-- MetisMenu CSS -->
<link href="$request.contextPath/assets/lib/sb-admin/2-1.0.7/bower_components/metisMenu/dist/metisMenu.min.css" rel="stylesheet">

<!-- Custom CSS -->
<link href="$request.contextPath/assets/lib/sb-admin/2-1.0.7/css/sb-admin-2.css" rel="stylesheet">

<!-- Custom Fonts -->
<link href="$request.contextPath/assets/lib/sb-admin/2-1.0.7/bower_components/font-awesome/css/font-awesome.min.css" rel="stylesheet" type="text/css">


    <!-- jQuery -->
    <script src="$request.contextPath/assets/lib/jquery/2.1.4/jquery-2.1.4.min.js"></script>
    
    <!-- Bootstrap Core JavaScript -->
    <script src="$request.contextPath/assets/lib/bootstrap/3.3.4/js/bootstrap.min.js"></script>
    
    <!-- Metis Menu Plugin JavaScript -->
    <script src="$request.contextPath/assets/lib/sb-admin/2-1.0.7/bower_components/metisMenu/dist/metisMenu.js"></script>

    <!-- Custom Theme JavaScript -->
    <script src="$request.contextPath/assets/lib/sb-admin/2-1.0.7/js/sb-admin-2.js"></script>
#printCss
</head>
<body>

  
 
			
            #parse("common/header.vm")
            
			 <div id="page-wrapper">$screen_content</div>
			 
			 
            #parse("common/rooter.vm")

       


    #printJavascript
    #printJsBlock
</body>

</html>

接下去我们就需要做一些解释:

如果你在处理某个请求时返回了a.vm模板,那么最终返回的页面是:将a.vm模板的内容填充layout页面的$screen_content占位符的内容,然后再将整个填充后的页面返回给用户。如果有兴趣你可以看一下大致的实现原理,其实很简单,就是先调用velocity引擎渲染请求返回的模板,将该渲染结果(一个String类型的字符串)作为一参数传递给layout页面,参数名称就是screen_content,然后再次调用引擎渲染layout页面,这样就会把该screen_content参数对应的值作为页面的一部分渲染出来了,从而实现整个页面的布局功能。

这样,我们就简单介绍了如何简单配置和使用velocity的layout功能了,这里你可以会有疑问了,如果我某个页面需要使用不同的layout页面,甚至我有些页面不需要使用layout功能,该怎么办?其实很简单,我们前面viewResolver配置中,配置的只是默认的layout页面的地址,如果你要使用不同的layout页面,只需在你要返回的页面中如下简单设置一下即可:

#set($layout = "/layout/layout2.vm") 

这样,我们就强制我们的这个页面使用的是layout2.vm这个页面布局。按照这个思路,如果我在某个特殊的页面,不想使用layout功能了,我们可以再指定另外一个layout页面,只不过这个layout页面内容比较特殊,它没有一般布局页面中有的那些页面统一的头部、尾部和菜单,只有如下所示的一行代码就可以了:

$screen_content

说到这里相信大家都对vm有一些了解了,最后我在把我项目webapp的文件目录结构贴出来大家应该也能配置自己的velocity+springmvc








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值