基类

public class Ftl_object_data_model  {
//三种基本属性
private boolean canRead=true;//是否能读取
private int length=;//长度
private String content;//内容
//内部小vo对象属性
private Ftl_object_data_model_inner fi = new Ftl_object_data_model_inner(); //非属性内部方法1
public boolean isCanWrite() {
return true;
}
//非属性内部方法2
public boolean canSend() {
return true;
} public boolean isCanRead() {
return canRead;
} public void setCanRead(boolean canRead) {
this.canRead = canRead;
} public int getLength() {
return length;
} public void setLength(int length) {
this.length = length;
} public String getContent() {
return content;
} public void setContent(String content) {
this.content = content;
} public Ftl_object_data_model_inner getFi() {
return fi;
} public void setFi(Ftl_object_data_model_inner fi) {
this.fi = fi;
} // @Override
// public Object exec(List arg0) throws TemplateModelException {
// return new SimpleNumber(((SimpleScalar)arg0.get(1)).getAsString().indexOf(((SimpleScalar)arg0.get(0)).getAsString()));
// }
// public TemplateModel exec(List arg0) throws TemplateModelException {
// return new SimpleNumber(((String)arg0.get(1)).indexOf((String)arg0.get(0)));
// }
} 基类中小vo 的类 public class Ftl_object_data_model_inner {
private boolean canRead=true;//是否能读取
private int length;//长度
private String content;//内容 public boolean isCanRead() {
return canRead;
} public void setCanRead(boolean canRead) {
this.canRead = canRead;
} public int getLength() {
return length;
} public void setLength(int length) {
this.length = length;
} public String getContent() {
return content;
} public void setContent(String content) {
this.content = content;
}
} main启动测试类 public class FtlTest {
public static void main(String[] args) throws IOException {
Configuration cfg = new Configuration();
cfg.setDirectoryForTemplateLoading(new File("F:\\king\\proj\\TKCard\\TKCard_cn_cn_Server\\src\\test\\java\\general\\ftl_test"));
// cfg.setObjectWrapper(ObjectWrapper.DEFAULT_WRAPPER);
cfg.setObjectWrapper(new DefaultObjectWrapper());
cfg.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER); //生成数据模型
//用map封装的数据模型
// Object root = testMapDataModel();
//直接用对象封装的数据模型
Object root = testObjectDataModel();
// 通过freemarker解释模板,首先需要获得Template对象
//用map封装的数据模型对应的模板
// Template template = cfg.getTemplate(testMapDataModelTemplate());
//直接用对象封装的数据模型对应的模板
Template template = cfg.getTemplate(testObjectDataModelTemplate()); // 定义模板解释完成之后的输出
//PrintWriter out = new PrintWriter(new BufferedWriter( new FileWriter(dir+"/out.txt")));
//直接控制台打印
OutputStreamWriter out = new OutputStreamWriter(System.out);
try {
// 解释模板
template.process(root, out);
} catch (TemplateException e) {
e.printStackTrace();
}
} /**
* 测试用map封装的数据模型
* @return
*/
public static Object testMapDataModel(){
Map root = new HashMap();
root.put("name1", "世界,你好");//模板里需要几个值,这边数据模型里就必须要塞几个值,缺一个就会报错(多塞不会报错),因为freeworker 不支持null,所以少塞会报错
root.put("name2", "我is大开发建设领导看风景");
root.put("name3", new Ftl_object_data_model());//如果传的是方法则上边map类型的数据模型的map只能去掉泛型了,不能用key为value皆为string的泛型了
return root;
}
/**
* 测试用map封装的数据模型对应的数据模板
* @return
*/
public static String testMapDataModelTemplate(){
return "ftl_map_data_model.ftl";
} /**
* 测试用vo对象封装的数据模型
* @return
*/
public static Object testObjectDataModel() {
Ftl_object_data_model fm = new Ftl_object_data_model();
return fm;
}
/**
* 测试用vo对象封装的数据模型对应的数据模板
* @return
*/
public static String testObjectDataModelTemplate(){
return "ftl_object_data_model.ftl";
}
} 数据模板 ---------------------------------------- 一、------------------------------------- <#-- 一、整个vo对象直接作为数据模型数据的基类Ftl_object_data_model 对象中的属性拿取方式-->
<#--基础属性直接拿取,无需带上对象变量(由于这边无需变量名,所以此基类变量名既不是root又不是fm)-->
<#--${root.length} 错误的写法,无需带root-->
<#--${fm.length} 错误的写法,无需带fm-->
<#--基类属性读取直接拿即可,其他属性一样,包括方法,直接拿取-->
${length}
<#--由于ftl一般都以字符串形式打印,所以Boolean类型的读取要特殊处理-->
<#--${canRead} 内部Boolean类型属性错误读取-->
<#--${canread} 内部Boolean类型属性错误读取-->
<#--${isCanRead()} 内部Boolean类型属性错误读取-->
<#--Boolean类型正确读写 固定格式 var?c -->
<#--boolean第一种读取,结果打印true or false-->
${canRead?c}
<#--Boolean第二种读取,结果打印yes or no 当canRead为真则取第一个参数值即yes,否则取第二个参数no-->
${canRead?string('yes','no')}
<#--非属性 的 Boolean类型get方法读取,即这个get方法拿的不是对象的属性,而仅仅是类中一个返回值为Boolean类型的方法-->
方法1:<#--${CanWrite()?c} 拿对象中非属性内部方法1错误拿法-->
方法1:<#--${canWrite()?c} 拿对象中非属性内部方法1错误拿法-->
方法1:<#--${canwrite()?c} 拿对象中非属性内部方法1错误拿法-->
方法1:<#--<#if CanWrite >true</#if> 拿对象中非属性内部方法1错误拿法-->
方法1:<#--<#if canwrite >true</#if> 拿对象中非属性内部方法1错误拿法--> 方法1:${isCanWrite()?c} <#-- 拿对象中非属性内部方法1正确拿法1-->
方法1:<#if isCanWrite() >true</#if> <#--拿对象中非属性内部方法1正确拿法-->
方法1:<#if canWrite >true</#if> <#--拿对象中非属性内部方法1正确拿法,这种方法是一种特殊的拿取方式,必须是在严格的is打头的get方法时才有用--> 方法2:<#--${cansend()?c} 拿对象中非属性内部方法2错误拿法-->
方法2:<#--<#if canSend >true</#if> 拿对象中非属性内部方法2错误拿法-->
方法2:<#--<#if cansend >true</#if> 拿对象中非属性内部方法2错误拿法--> 方法2:${canSend()?c} <#-- 拿对象中非属性内部方法2正确拿法1-->
方法2:<#if canSend() >true</#if> <#--拿对象中非属性内部方法2正确拿法--> ---------------------------------------- 二、------------------------------------- <#-- 二、整个vo对象直接作为数据模型数据的基类Ftl_object_data_model 对象中的子类属性 小vo对象中的属性拿取方式-->
<#--直接用小vo 被new 时的变量名.属性 或 .方法即可 拿取 方式和直接拿基类中的属性一样的-->
${fi.length}
${fi.isCanRead()?c}
<#if fi.isCanRead() >true</#if>
<#if fi.canRead >true</#if> <#-- 注:几个重要的语法规则: 、FreeMarker的插值有如下两种类型:,通用插值${expr};,数字格式化插值:#{expr}或#{expr;format}
、??:判断某个变量是否存在,返回boolean值 类似 var?if_exists
、var!xxx:指定缺失变量的默认值 类似 var?default(xxx) 而 ${!var?c}表明非var,即当var为真时结果求假,!此表非含义
、使用lt、lte、gt和gte来替代<、<=、>和>= 也可以使用括号<#if (x>y)>
、内置函数: 调用区别于属性的访问,属性访问用.访问,而内置函数用?访问如var?if_exists
、注意${}为变量的渲染显示,而<>为定义等操作符的定义
、对于库中的变量修改,使用in关键字 <#assign mail="jsmith@other.com" in my>
、stringA[M .. N] 取子字符串,类似substring(stringA, M, N)
、List片段可以采用: products[..] or products[..] 的格式进行定义,当只局限于数字
<#assign c= [,,,,,,,]>
<#list c[..] as v>
${v}
</#list>
、freemarker可用"["代替"<".在模板的文件开头加上[#ftl].
、注释语法 <#-- 注释部分 -->
<#-- 由于杀念11注释语法破坏了整体的注释,所以这边由加了个注释头标签
、 数字输出的另外一种方式 #{c.a;m0} 区别于${x},这个例子是用于输出数字的格式化,保留小数的位数,详细如下
数字格式化插值可采用#{expr;m1M2}形式来格式化数字,其中: m1:小数部分最小1位 M2:小数部分最大2位 即大小m代表不同含义
、在定义字符串的时候,可以使用''或者"",对特殊字符,需要使用\进行转义
、如果存在大量特殊字符,可以使用${r"..."}进行过滤 如 ${r"${foo}"} ${r"C:\foo\bar"}
、Map对象的key和value都是表达式,但是key必须是字符串 可以混合使用.和[""]访问 book.author["name"] //混合使用点语法和方括号语法
、为了处理缺失变量,FreeMarker提供了两个运算符: 用于防止对象不存在而导致的异常 !:指定缺失变量的默认值 ??:判断某个变量是否存在,返回boolean值
、noparse指令指定FreeMarker不处理该指定里包含的内容,该指令的语法格式如下: <#noparse>...</#noparse>
、?html 用于将字符串中可能包含的html字符,进行过滤.
${firstName?html} 使用?html对html字符进行过滤、格式化处理 escape , noescape指令,对body内的内容实用统一的表达式
看如下的代码:
<#escape x as x?html>
First name:${firstName}
Last name:${lastName}
Maiden name:${maidenName}
</#escape>
上面的代码等同于:
First name:${firstName?html}
Last name:${lastName?html}
Maiden name:${maidenName?html}
、<#assign name1=value1 name2=value2 / > 可以同时定义多个变量
也可以使用循环来给变量赋值
<#assign x>
<#list ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"] as n>
n:${n}
</#list>
</#assign>
x:${x} 执行结果:
x:
n:星期一
n:星期二
n:星期三
n:星期四
n:星期五
n:星期六
n:星期天
说明:不是先打印n:${n}的循环值,而是先打印 x:${x}的值。含义就是先定义一个x,x的内容为 循环list,每次循环渲染显示的内容
n:${n} 的值 为x中的一个元素,全部循环完,x的值也组装完了,结果打印显示x:${x}。记住不是说list为x中的list,即不是为x注入一个list(这
就是为啥最后打印x时前边都有n:而不是和原list内容一样的原因,表明此list不是x中的属性,即此list和x没什么关系,此仅借用一下list机制而已),
而是通过list机制 进行循环得出临时值作为x的元素。
、setting指令,用于动态设置freeMarker的运行环境:
该指令用于设置FreeMarker的运行环境,该指令的语法格式如下:<#setting name=value>,在这个格式中,name的取值范围包含如下几个:
locale:该选项指定该模板所用的国家/语言选项
number_format:指定格式化输出数字的格式
boolean_format:指定两个布尔值的语法格式,默认值是true,false
date_format,time_format,datetime_format:指定格式化输出日期的格式
time_zone:设置格式化输出日期时所使用的时区
、<#return> 用于退出宏的运行
、调用Java方法:
如:
public class A implements TemplateMethodModelEx{
@Override
public Object exec(List arg0) throws TemplateModelException {
return new SimpleNumber(((SimpleScalar)arg0.get()).getAsString().indexOf(((SimpleScalar)arg0.get()).getAsString()));
}

public TemplateModel exec(List arg0) throws TemplateModelException {
return new SimpleNumber(((String)arg0.get()).indexOf((String)arg0.get()));
}
}
封装数据模型时用map模型(如果用vo对象模型的话可能需要vo中有个map,此map的效果等同于直接用map模型),直接 map.put("method",new A()); method可以任意变量名
由于此要put一个对象,所以此map模型用到的map就不能用Map<String,String>了,即不用带泛型,用 Map root = new HashMap();
下边就是到模板了,模板里表达式格式为:<#assign x = "something"> ${method("met",x)} 即先定义一个变量x,然后调用表达式method("met",x),此表达式传2个
参数,当解析模板执行到此表达式时会将此表达式的2个参数直接传到A类中的exec方法中的参数,exec方法参数为list,那模板中传几个参数都是以String类型或
SimpleScalar(ftl包装string用的对象,可以调用getAsString()得到string内容)类型直接传到exec的参数list中的,传几个过来就都封装到这个list中,exec执行
结果返回给模板 ${结果} 渲染显示出来。 说明:调用Java方法时需要java类实现TemplateMethodModel 或 TemplateMethodModelEx接口,但是好像会覆盖掉属性的访问,即这个类中的其他属性可能就没法访问了(这个是否能访问没测过)
即要调用的java方法所在类 必须实现TemplateMethodModel接口,即实现 exec方法 即 public TemplateModel exec(List arg0) throws TemplateModelException
或 public Object exec(List list) throws TemplateModelException 方法。
在模板解析时模板中调用表达式时会立即调用到java类中的上边实现的exec方法,exec方法返回值 返回给 模板中表达式处 渲染显示出来。 -->

最新文章

  1. JavaScript高级程序设计-(1)html中使用JavaScript
  2. java学习之面向对象(3)
  3. asp.net XMLHttpRequest 进度条以及lengthComputable always false的解决办法
  4. sql的列的说明
  5. CentOS6修改主机名(hostname)及 修改/etc/hosts 文件,增加ip和hostname的映射关系(转)
  6. 自定义属性 view
  7. zedboard如何从PL端控制DDR读写(七)
  8. configure: error: Please reinstall the libcurl distribution
  9. memwatch内存泄露检测工具
  10. Sqoop实现自定义job的增量导入
  11. 搭建高性能计算环境(十)、应用软件的安装之Wien2k
  12. Elasticsearch template configuration
  13. POJ2891——Strange Way to Express Integers(模线性方程组)
  14. ASP.NET MVC 简易在线书店
  15. Hibernate 注解 字段不映射的注解
  16. impdp/expdp 总结
  17. Hash Map (Hash Table)
  18. (转) 通过input分片的大小来设置map的个数
  19. 浅谈MVC异常处理
  20. 洛谷P2179 骑行川藏

热门文章

  1. Frist
  2. 基于 HTML5 WebGL 与 GIS 的智慧机场大数据可视化分析【转载】
  3. Java容器的常见问题
  4. python爬取某站新闻,并分析最近新闻关键词
  5. 装numpy 环境:python3.4+ windows7 +64位系统
  6. RabbitMQ AMQP 事务机制
  7. mybatis 源码赏析(一)sql解析篇
  8. Vue 里面对树状数组进行增删改查 的方法
  9. MATLAB 动图绘制、保存
  10. Bootstrap Blazor 组件库