velocity自定义标签和指令

velocity本身支持自定义标签和指令的扩展,

在 Velocity 模板语言的语法中,以美元符 $ 开头的为变量的声明或者引用,而以井号 # 开头的语句则为 Velocity 的指令(Directive)。

velocity支持的指令有:#set,#foreach,#if #else #end,#parse,#include,#evaluate,#define,#macro,

在velocity的jar包中的directive.properties中定义了这些实现:

[html] view plaincopyprint?

  1. directive.1=org.apache.velocity.runtime.directive.Foreach
  2. directive.2=org.apache.velocity.runtime.directive.Include
  3. directive.3=org.apache.velocity.runtime.directive.Parse
  4. directive.4=org.apache.velocity.runtime.directive.Macro
  5. directive.5=org.apache.velocity.runtime.directive.Literal
  6. directive.6=org.apache.velocity.runtime.directive.Evaluate
  7. directive.7=org.apache.velocity.runtime.directive.Break
  8. directive.8=org.apache.velocity.runtime.directive.Define
directive.1=org.apache.velocity.runtime.directive.Foreach
directive.2=org.apache.velocity.runtime.directive.Include
directive.3=org.apache.velocity.runtime.directive.Parse
directive.4=org.apache.velocity.runtime.directive.Macro
directive.5=org.apache.velocity.runtime.directive.Literal
directive.6=org.apache.velocity.runtime.directive.Evaluate
directive.7=org.apache.velocity.runtime.directive.Break
directive.8=org.apache.velocity.runtime.directive.Define

自定义标签和指定,比如我们定义了下面的remoteVelocity指令

[html] view plaincopyprint?

  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2. <html xmlns="http://www.w3.org/1999/xhtml">
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=gbk" />
  5. <title>click ok page</title>
  6. </head>
  7. <body>
  8. This app runs well
  9. #set($monkey= {"banana" : "good", "roast beef" : "bad"})
  10. #remoteVelocity("namespace","velocityname",$monkey)
  11. </body>
  12. </html>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gbk" />
<title>click ok page</title>
</head>
<body>
  This app runs well

  #set($monkey= {"banana" : "good", "roast beef" : "bad"})

  #remoteVelocity("namespace","velocityname",$monkey)
</body>
</html>

要对这个指令的实现要继承Directive这个类,这个宏我们可以从其他服务获取vm的内容,动态渲染,这种方式可以统一管理公共模板,

[java] view plaincopyprint?

  1. import java.io.IOException;
  2. import java.io.Serializable;
  3. import java.io.StringWriter;
  4. import java.io.Writer;
  5. import java.util.HashMap;
  6. import java.util.Map;
  7. import org.apache.velocity.VelocityContext;
  8. import org.apache.velocity.app.VelocityEngine;
  9. import org.apache.velocity.context.InternalContextAdapter;
  10. import org.apache.velocity.exception.MethodInvocationException;
  11. import org.apache.velocity.exception.ParseErrorException;
  12. import org.apache.velocity.exception.ResourceNotFoundException;
  13. import org.apache.velocity.runtime.directive.Directive;
  14. import org.apache.velocity.runtime.parser.node.Node;
  15. import org.apache.velocity.runtime.parser.node.SimpleNode;
  16. import org.springframework.beans.factory.annotation.Autowired;
  17. import com.alibaba.citrus.service.template.TemplateService;
  18. import com.alibaba.click.util.HostUtil;
  19. public class RemoteVelocity extends Directive{
  20. @Autowired
  21. TemplateService templateService;
  22. private static final VelocityEngine velocityEngine = new VelocityEngine();
  23. @Override
  24. public String getName() {
  25. return "remoteVelocity";
  26. }
  27. @Override
  28. public int getType() {
  29. return LINE;
  30. }
  31. @Override
  32. public boolean render(InternalContextAdapter context, Writer writer,
  33. Node node) throws IOException, ResourceNotFoundException,
  34. ParseErrorException, MethodInvocationException {
  35. SimpleNode sn_region = (SimpleNode) node.jjtGetChild(0);
  36. String region = (String)sn_region.value(context);
  37. SimpleNode sn_key = (SimpleNode) node.jjtGetChild(1);
  38. Serializable key = (Serializable)sn_key.value(context);
  39. SimpleNode sn_data = (SimpleNode) node.jjtGetChild(2);
  40. Object data = sn_data.value(context);
  41. Map map = new HashMap();
  42. map.put("data", data);
  43. //      String vel = HostUtil.getResponseText("http://127.0.0.1/index.html");
  44. String vel="#foreach($member in $data.entrySet())<li>$member.key - $member.value</li>#end ";
  45. writer.write(renderTemplate(map,vel));
  46. return true;
  47. }
  48. public static String renderTemplate(Map params,String vimStr){
  49. VelocityContext context = new VelocityContext(params);
  50. StringWriter writer = new StringWriter();
  51. try {
  52. velocityEngine.evaluate(context, writer, "", vimStr);
  53. } catch (ParseErrorException e) {
  54. // TODO Auto-generated catch block
  55. e.printStackTrace();
  56. } catch (MethodInvocationException e) {
  57. // TODO Auto-generated catch block
  58. e.printStackTrace();
  59. } catch (ResourceNotFoundException e) {
  60. // TODO Auto-generated catch block
  61. e.printStackTrace();
  62. } catch (IOException e) {
  63. // TODO Auto-generated catch block
  64. e.printStackTrace();
  65. }//渲染模板
  66. return writer.toString();
  67. }
  68. }
import java.io.IOException;
import java.io.Serializable;
import java.io.StringWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;

import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.context.InternalContextAdapter;
import org.apache.velocity.exception.MethodInvocationException;
import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.apache.velocity.runtime.directive.Directive;
import org.apache.velocity.runtime.parser.node.Node;
import org.apache.velocity.runtime.parser.node.SimpleNode;
import org.springframework.beans.factory.annotation.Autowired;

import com.alibaba.citrus.service.template.TemplateService;
import com.alibaba.click.util.HostUtil;

public class RemoteVelocity extends Directive{

	@Autowired
	TemplateService templateService;

	private static final VelocityEngine velocityEngine = new VelocityEngine();

	@Override
	public String getName() {
		return "remoteVelocity";
	}

	@Override
	public int getType() {
		return LINE;
	}

	@Override
	public boolean render(InternalContextAdapter context, Writer writer,
			Node node) throws IOException, ResourceNotFoundException,
			ParseErrorException, MethodInvocationException {
		SimpleNode sn_region = (SimpleNode) node.jjtGetChild(0);
        String region = (String)sn_region.value(context);
        SimpleNode sn_key = (SimpleNode) node.jjtGetChild(1);
        Serializable key = (Serializable)sn_key.value(context);   

		SimpleNode sn_data = (SimpleNode) node.jjtGetChild(2);
		Object data = sn_data.value(context);
		Map map = new HashMap();
		map.put("data", data);
//		String vel = HostUtil.getResponseText("http://127.0.0.1/index.html");
		String vel="#foreach($member in $data.entrySet())<li>$member.key - $member.value</li>#end ";
		writer.write(renderTemplate(map,vel));
        return true;
	}

	public static String renderTemplate(Map params,String vimStr){
        VelocityContext context = new VelocityContext(params);
        StringWriter writer = new StringWriter();
        try {
			velocityEngine.evaluate(context, writer, "", vimStr);
		} catch (ParseErrorException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (MethodInvocationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ResourceNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}//渲染模板
        return writer.toString();
	}

}

node.jjtGetChild(2) 这个方法可以获取对应指令的参数,下标从0开始,

在web工程的WEB-INF下面定义velocity.properties这个配置文件,用户扩展的指令最好放到这个文件里面,velocity的jar包里面提供了默认实现,我们可以覆盖重新定义自己的扩展,类就是对应自己的扩展类的类名

#自定义标签

[html] view plaincopyprint?

  1. userdirective=com.alibaba.click.test.RemoteVelocity
userdirective=com.alibaba.click.test.RemoteVelocity

这样启动后就可以正常使用了。

Directive的三个方法:

[html] view plaincopyprint?

  1. getName:指令的名称
  2. getType:当前有LINE,BLOCK两个值,line行指令,不要end结束符,block块指令,需要end结束符
  3. public boolean render(InternalContextAdapter context, Writer writer,
  4. Node node) 具体处理过程
getName:指令的名称
getType:当前有LINE,BLOCK两个值,line行指令,不要end结束符,block块指令,需要end结束符
public boolean render(InternalContextAdapter context, Writer writer,
			Node node) 具体处理过程

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow

原文地址:https://www.cnblogs.com/skiwndhw/p/10352022.html

时间: 2024-08-29 11:30:32

velocity自定义标签和指令的相关文章

freemarker自定义标签(三)-nested指令

freemarker自定义标签 1.nested指令 是可选的,可以在<#macro>和</#macro>之间使用在任何位置和任意次数 2.示例说明 <#macro tag> <#nested/> </#macro> <@tag> <ul> <li>1</li> <li>2</li> <li>3</li> <li>4</li>

JSP自定义标签

假设 向浏览器输出当前客户的IP地址 ,我们现在可以这样写 <% //获取当前用户的IP地址 String ip=request.getRemoteHost(); out.print("当前用户的IP地址是:"+ip); %> 但我们现在为了要在jsp页面尽量减少java代码,这个时候我们可以向前面学标签一样,自己来定义一个标签,通过调用标签来达到实现显示客户端的ip地址. 首先第一步我们要创建一个普通的java类,继承SimpleTagSupport类,叫标签处理器类(用

Javaweb学习笔记6—EL表达式与JSTL及自定义标签

 前几天博客被黑了,导致博客登陆不上,把前几天应该发的东西的东西重新发一遍 今天来讲javaweb的第六阶段学习. EL表达式与JSTL及自定义标签是对上篇文章介绍的JSP的扩展,不能说是很重要的东西,但是也要了解. 老规矩,首先先用一张思维导图来展现今天的博客内容. ps:我的思维是用的xMind画的,如果你对我的思维导图感兴趣并且想看到你们跟详细的备注信息,请点击下载 另外:如果图看不清的话请右击---在新窗口中打开会清楚很多. 一.EL表达式 1,EL简介 Expression Lan

讲解JSP自定义标签

一.基本概念 1.标签(Tag) 标签是一种XML元素,通过标签可以使JSP网页变得简洁并且易于维护,还可以方便地实现同一个JSP文件支持多种语言版本.由于标签是XML元素,所以它的名称和属性都是大小写敏感的. 2.标签库(Tag library) 由一系列功能相似.逻辑上互相联系的标签构成的集合称为标签库. 3.标签库描述文件(Tag Library Descriptor) 标签库描述文件是一个XML文件,这个文件提供了标签库中类和JSP中对标签引用的映射关系.它是一个配置文件,和web.xm

10JSP自定义标签

1标签(Tag): 标签是一种XML元素,通过标签可以使JSP网页变得简洁并且易于维护,还可以方便地实现同一个JSP文件支持多种语言版本.由于标签是XML元素,所以它的名称和属性都是大小写敏感. 标签库(Tag library): 由一系列功能相似.逻辑上互相联系的标签构成的集合称为标签库. 标签库描述文件(Tag Library Descriptor): 标签库描述文件是一个XML文件,这个文件提供了标签库中类和JSP中对标签引用的映射关系.它是一个配置文件,和web.xml是类似的. 标签处

Web学习之自定义标签

1.编写一个实现Tag接口的Java类(标签处理器类) 1 package me.gacl.web.tag; 2 3 import java.io.IOException; 4 5 import javax.servlet.http.HttpServletRequest; 6 import javax.servlet.jsp.JspException; 7 import javax.servlet.jsp.JspWriter; 8 import javax.servlet.jsp.PageCon

JavaWeb之自定义标签&amp;JSTL&amp;国际化(九)

自定义标签 简介 自定义标签由于没练习,所以掌握的不是很深,但是对于我而言足够可以应付用户登录注册案例和购物车案例,有时间还是多了解的好 1. 自定义标签简介 1.作用:替换JSP页面中的java脚本(<%%>).(官方推荐:JSP2.0开始) 2. 开发步骤 1. 自定义一个类继承SimpleTagSupport实现doTag方法 2. WEB-INF,建立tld文件,定义标签地址/定义标签内容 3. jsp页面使用taglib指令引入uri地址,prefix定义标签名,直接在页面调用这个标

freemarker自定义标签

freemarker自定义标签 1.自定义标签说明 宏变量存储模板片段可以被用作自定义指令macro 2.示例说明 <html> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <title>freemarker自定义标签</title> </head> <body> <#--

Java Web总结十六之一自定义标签

一.自定义标签简介 1.为什么要使用自定义标签? 自定义标签主要用于移除Jsp页面中的<%java%>代码. 2.开发自定义标签的步骤: 1)开发自定义标签处理类,该类需要实现SimpleTag接口/SimpleTagSupport类,重写doTag()方法. 2)编写标签库描述符(tld)文件,在tld文件中对自定义标签进行描述,并放置在WEB-INF/目录下. 3)完成以上操作,即可在JSP页面中导入和使用自定义标签. 二.自定义标签描述 1.实现SimpleTag接口的标签通常称为简单标