freemarker资料!

http://freemarker.org/index.html

  freemarker正常生成HTML的模板引擎,公司需求将书籍来源的数据发放到不同的渠道,每个渠道生成特定的模板,这样数据自动生成相应的格式,主要是生成xml格式,所以根据网上的Demo改成了对应项目测试的Demo.--------------------此为背景。

正常的模板文件.flt的,但是发现改成.xml格式的也完全没有问题,我表示非常高兴,哇卡卡卡~

网上有很多标签大全,我就捡我用过的标签写:(不断的补充ing。。。)

 1.<#if></#if>

   <#elseif> 跟java的if else一个意思,后面加表达式, if 和elseif 最后公用一个</#if>结束标签。

    freemarker对于null值要求非常严格,会报错,所以所有值必须加判断是否存在<#if (metadata.EISBN)!""> 我是这么用的,还有别的方法  回头把标签大全粘过来~~~

 2.<#list></#list>

    循环这个标签非常好用,<#list Onix as metadata> 

    item_index:当前变量的索引值 
    item_has_next:是否存在下一个对象 其中item名称为as后的变量名,如stu 

 3.<#assign/>

<#assign s="sss"/>这是正常声明一个字符串
    <#assign l=0..100/>这是声明一个int区间的集合
  <#assign s=audience.audienceValue/>这是取root里面的值

 4.${exp}插值,里面直接放表达式

${.now?string("yyyyMMdd")} 这是新加的标签,表示当前时间,后面可以生成不同格式的。

 5.字符串处理(跟java的都一样)

 

?split("-")根据"-"将字符串分成list
    ?index_of("-")判断是否存在字符串"-",存在返回下表,不存在返回-1

 6.<#--> </#-->注释标签

目前就用了这么多标签就搞定了

 

 

如果要输出一个集合,那么就必须先了解freemarker中的循环、判断等流程语法

if判断流程语法

基本语法

<#if boolean></#if>
或者<#if boolean><#else></#if>
或者<#if boolean>
<#if boolean></#if>
</#if>
或者<#if boolean><#elseif boolean></#if>

其中第三种你应该这么理解,先去除最后的</#if>那只看前面的,就是这个逻辑,如果怎么样,否则如果怎么样,最后的</#if>你可以理解成仅仅是一个结束的标志,没有任何逻辑含义。

比如

<#if product.id<10>-------------如果id小于10

该产品ID<10

<#elseif product.id==12>--------否则如果id等于12

该产品ID==12

</#if>----------------------------结束标志

Eg:将上面的例子修改下

<#if product.id<10>-------------如果id小于10

该产品ID<10

<#elseif product.id==1>--------否则如果id等于1

该产品ID==12

</#if>----------------------------结束标志

大家觉得逻辑对吗?如果id小于10,否则id等于1,逻辑不对。

那我想实现判断的嵌套呢?也很简单,如下

<#if product.id<10>

该产品ID<10

<#if product.id==1>

该产品ID==1

</#if>
</#if>

那么支持boolean的比较运算符有哪些呢?

比较预算符有

a、=(或者==):判断两个值是否相等.
b、!=:判断两个值是否不相等
c、 >(或者gt):判断坐标值是否大于右边值
d、 >=(或者gte):判断坐标值是否大于等于右边值
e、 <(或者lt):判断左边值是否小于右边值
f、 <=(或者lte):判断左边值是否小于等于右边值        

刚才我们说的if else逻辑的布尔值都是比较预算符结果,还有多个条件的逻辑预算符呢?先来看看逻辑预算符有哪些吧。逻辑预算符有&&(与)、||(或)、!(非)

通过一个例子来看看

<#if product.id<10&& !product.name ??>

该产品ID<10,且产品名(${product.name})为空

</#if>

第一点,我们需要看的是&&,没有难度吧,就是两个条件均为true才执行

第二点,需要说明的是??,这里就牵扯掉有一个特殊的问题,就是在freemarker中,如何判断一个字符串为空呢?方法就是用??(?if_exists,?exists) 如果不为空返回true,否则返回false 

第三点,需要看的是!,这点也没有疑问吧,取反,逻辑预算符

逻辑运算符有三个,我们演示了两个了,剩下一个或也很简单。


xml文档转义字符

<#assign title="111<111>111&1111"?xhtml?replace("&","&")/>
${title}的值为111<111>111&1111

OK~


 

在内部,模板中可用的变量都是实现了freemarker.template.TemplateModel接口的Java对象。但在你自己的数据模型中,可以使用基本的Java集合类作为变量,因为这些变量会在内部被替换为适当的TemplateModel类型。这种功能特性被称作是object wrapping对象包装。对象包装功能可以透明地把任何类型的对象转换为实现了TemplateModel接口类型的实例。这就使得下面的转换成为可能,如在模板中把java.sql.ResultSet转换为序列变量,把javax.servlet.ServletRequest对象转换成包含请求属性的哈希表变量,甚至可以遍历XML文档作为FTL变量。

 模板实现时会将非TemplateModel对象替换为TemplateModel对象。通过ObjectWrapper实现类的 的   TemplateModeal wrap(java.lang.Object)方法实现。

 ObjectWrapper.DEFAULT_WRAPPER:它使用SimpleScalar来替换String,SimpleNumber来替换Number,SimpleSequence来替换List和数组,SimpleHash来替换Map,TemplateBooleanModel.TRUE或TemplateBooleanModel.FALSE来替换Boolean,freemarker.ext.dom.NodeModel来替换W3C组织定义的DOM模型节点类型。对于Jython类型的对象,包装器会调用freemarker.ext.jython.JythonWrapper。而对于其他对象,则会调用BEAN_WRAPPER。

 ObjectWrapper.BEANS_WRAPPER:它可以通过Java 的反射机制来获取到Java Bean的属性和其他任意对象类型的成员变量。

 

 

freemarker.template.TemplateException: Expected hash. mainKey evaluated instead to freemarker.template.SimpleScalar on line 32, column 19 in evertrip/diyquote/test.ftl.
报这个错 说明数据转换有问题  不能转换成freemarker认可的格式

model.addAttribute("endtime", time);time为Date类型 flt中 ${begintime?string("yyyy-MM-dd")}就会报错  ${begintime?date("yyyy-MM-dd")}正常  反之一样