1、Freemarker模板的文件后缀名
2、Freemarker其实是一种比较简单的网页展示技术,说白了就是网页模板和数据模型的结合体。这种结合模式的好处就是,分离了网页界面设计人员和编程人员的工作,让他们各司其职。
据个人理解,Freemarker大致的工作方式是,网页模板里面嵌入了数据模型中的数据、Freemarker自定义流程控制语言、Freemarker自定义的操作函数等等,在装载网页的时候,Freemarker模板自动从数据模型中提取数据,并解释整个网页为我们熟知的HTML页面。
在B/S程式设计中,常常有美工和程序员二个角色,他们具有不同专业技能:美工专注于表现——创建页面、风格、布局、效果等等可视元素;而程序员则忙于创建程式的商业流程,生成设计页面要显示的数据等等。
很多时候,要显示的资料在设计的时候并不存在,它们一般是在运行时由程式产生的,比如执行“价格不高于800NT的USB Disk”查询的返回结果。这种技术需求产生了JSP等Scriptlet,JSP十分强大,但是也常常被滥用,并导致一些不良的后果,将逻辑和表现混合在一起。,破坏了美工和程序员职责的正常分解使JSP页面难以阅读和维护。
模板引擎就是为了解决上面的问题而产生的。在设计HTML的时候,我们加入一些特定指令来指定要插入哪些数据,这些加了特殊指令的HTML或者其他文本,我们称为模板(Template)。而模板引擎会在输出页面时,用适当的数据替代这些代码
模板和嵌入JSP的HTML是不同的,模板指令只有很有限的编程能力,可以避免混入商业逻辑。
总结
简单的说,FreeMarker就是一种用Java编写的模板引擎,它根据模板输出多种规格的文本。特别指出的是,FreeMarker与Web应用框架无关,它同样可以应用在非Web应用程序环境中,而且,FreeMarker并不是只能生成HTML页面,它也可以生成各种文本,如XML/RTF/Java源代码等。
Freemarker是一个非常优秀的模版引擎,这个模版引擎可用于任何场景,FreeMarker负责将数据模型中的数据合并到模版中,从而生成标准输出。
FreeMarker特别适应与MVC模式的Web应用,通常有Java程序准备要显示的数据,由FreeMarker模版引擎来生成页面,而FreeMarker模版则提供页面布局支持,从而能更好地规范MVC架构,保证视图逻辑和业务逻辑分离。
语法:

直接调用后台方法代码
<PRE class=ftl name="code">默认两种用法   
${!("")}   
${default("")}</PRE>   
<@s.property value="%{getPieceByType(type)}"/>   
getPieceByType为方法名,type为值  

Ftl代码默认两种用法   ${!("")}   ${default("")}  默认两种用法 
${!("")} 
${default("")} 
<@s.property value="%{getPieceByType(type)}"/> 
getPieceByType为方法名,type为值 

时间格式化的方法代码 
最好加上 判断下c时候存在   
<#if c??>   
${c.addtime?string("yyyy-MM-dd HH:mm:ss")   
</#if>  

最好加上判断下c时候存在 
<#if c??> 
${c.addtime?string("yyyy-MM-dd HH:mm:ss") 
</#if>  

判断长度并截取代码 
<#if c.titleH1??>   
<#if c.titleH1?length lt 33>   
${c.titleH1}   
action 中   
配置    
private String inputPath;    
private HttpServletResponse servletResponse;    

public void setServletResponse(HttpServletResponse arg0) {   
this.servletResponse = arg0;    
}   

public HttpServletResponse getServletResponse() {   
return servletResponse;   
}    

public String formguideDownloads() throws Exception {   
formguide.setTemplateId(formguide.getTemplateId()+".jsp");     
return SUCCESS;         
}   

xml中配置   
<action name="formguideDownloads" class="com.jcauto.cms.action.FormguideAction" method="formguideDownloads">       
<result name="success" type="stream">       
<param name="contentType">text/plain;charset=utf-8</param>     
<param name="inputName">inputStream</param>         
<param name="contentDisposition">attachment;filename="${formguide.templateId}"</param>     
<param name="bufferSize">4096</param>       
</result>     
</action>      

页面上   
formguide/formguideDownloads.action?formguide.templateId=${form.templateId?if_exists}&inputPath=${fileUrlFileName?if_exists}${form.templateId?if_exists}.jsp" <#else>   
${c.titleH1[0..32]}...   
</#if>   
</#if>   
注意length是从0开始算所以如果想截取33位就使用0..32就可以了  

<#if c.titleH1??> 
<#if c.titleH1?length lt 33> 
${c.titleH1} 
action 中 
配置 
private String inputPath; 
private HttpServletResponse servletResponse; 

public void setServletResponse(HttpServletResponse arg0) { 
this.servletResponse = arg0; 
} 

public HttpServletResponse getServletResponse() { 
return servletResponse; 
} 

public String formguideDownloads() throws Exception { 
formguide.setTemplateId(formguide.getTemplateId()+".jsp");  
return SUCCESS;      
} 

xml中配置 
<action name="formguideDownloads" class="com.jcauto.cms.action.FormguideAction" method="formguideDownloads">    
<result name="success" type="stream">    
<param name="contentType">text/plain;charset=utf-8</param>  
<param name="inputName">inputStream</param>      
<param name="contentDisposition">attachment;filename="${formguide.templateId}"</param>  
<param name="bufferSize">4096</param>    
</result>  
</action>   

页面上 
formguide/formguideDownloads.action?formguide.templateId=${form.templateId?if_exists}&inputPath=${fileUrlFileName?if_exists}${form.templateId?if_exists}.jsp" <#else> 
${c.titleH1[0..32]}... 
</#if> 
</#if> 
注意length是从0开始算所以如果想截取33位就使用0..32就可以了 

List-map使用代码 
ftl.list   
<#list List as list>   
${list}   
</#list>   
list_index取出行号索引从0开始                 
formguideList?size 可以判断list大小   
这里多说一句有很多list中属性的用法不一一列举,大家可以查下ftl API    
ftl.map   
<#list Map?keys as s>   
${Map[s]}   
</#list>   

s.list   
<@s.iterater value="List" var=list>   
</@s.iterater>   
s.if   
<@s.if>   
</@>   
<@s.else>   
</@>   
ftl.if   
<#if>   
<#else>   
</#if>  

ftl.list 
<#list List as list> 
${list} 
</#list> 
list_index取出行号索引从0开始              
formguideList?size 可以判断list大小 
这里多说一句有很多list中属性的用法不一一列举,大家可以查下ftl API 
ftl.map 
<#list Map?keys as s> 
${Map[s]} 
</#list> 

s.list 
<@s.iterater value="List" var=list> 
</@s.iterater> 
s.if 
<@s.if> 
</@> 
<@s.else> 
</@> 
ftl.if 
<#if> 
<#else> 
</#if> 

上传代码 
<form actoin="${path}/piece/findPiece.action" name="form1" method="Post" enctype="multipart/form-data">    
<s:file name="sfile"/>   
</form>   
后台action中配置   
File sfile;   
String sfileName;   
String sfileType;  

<form actoin="${path}/piece/findPiece.action" name="form1" method="Post" enctype="multipart/form-data"> 
<s:file name="sfile"/> 
</form> 
后台action中配置 
File sfile; 
String sfileName; 
String sfileType; 

下载代码 
前台   
<a href="${path}/formguide /formguideDownloads.action?formguide.templateId=${form.templateId?if_exists}& amp;inputPath=${fileUrlFileName?if_exists}${form.templateId?if_exists}.jsp"& gt;下载</a> |     

后台   
private HttpServletResponse servletResponse;     
private String inputPath;    
public void setServletResponse(HttpServletResponse arg0) {   
this.servletResponse = arg0;    
}   

public HttpServletResponse getServletResponse() {   
return servletResponse;   
}   
public String formguideDownloads() throws Exception {   
formguide.setTemplateId(formguide.getTemplateId()+".jsp");     
return SUCCESS;         
}   

public InputStream getInputStream() throws Exception {    
return ServletActionContext.getServletContext().getResourceAsStream(   
inputPath);     
}   

xml   
<action name="formguideDownloads" class="com.jcauto.cms.action.FormguideAction" method="formguideDownloads">       
<result name="success" type="stream">       
<param name="contentType">text/plain;charset=utf-8</param>     
<param name="inputName">inputStream</param>         
<param name="contentDisposition">attachment;filename="${formguide.templateId}"</param>     
<param name="bufferSize">4096</param>       
</result>     
</action>    

前台 
<a href="${path}/formguide /formguideDownloads.action?formguide.templateId=${form.templateId?if_exists}& amp;inputPath=${fileUrlFileName?if_exists}${form.templateId?if_exists}.jsp"& gt;下载</a> |  

后台 
private HttpServletResponse servletResponse;  
private String inputPath; 
public void setServletResponse(HttpServletResponse arg0) { 
this.servletResponse = arg0; 
} 

public HttpServletResponse getServletResponse() { 
return servletResponse; 
} 
public String formguideDownloads() throws Exception { 
formguide.setTemplateId(formguide.getTemplateId()+".jsp");  
return SUCCESS;      
} 

public InputStream getInputStream() throws Exception { 
return ServletActionContext.getServletContext().getResourceAsStream( 
inputPath);  
} 
xml 
<action name="formguideDownloads" class="com.jcauto.cms.action.FormguideAction" method="formguideDownloads">    
<result name="success" type="stream">    
<param name="contentType">text/plain;charset=utf-8</param>  
<param name="inputName">inputStream</param>      
<param name="contentDisposition">attachment;filename="${formguide.templateId}"</param>  
<param name="bufferSize">4096</param>    
</result>  
</action>    

Ftl中的循环代码 
使用宏标签来循环生成固定的值   
其中local中来定义值   
repeat用来生成   
<#macro repeat count>   
<#local y = "<img src='http://www.jcauto.com.cn/ProConsole/images/star0506.gif' border='0' alt='' width='11' height='11'/>">   
<#list 1..count as x>   
${y} ${count}/${x}: <#nested>   
</#list>   
</#macro>   
<@repeat count=3>${y?default("?")} ${x?default("?")} ${count?default("?")}</@repeat>  

使用宏标签来循环生成固定的值 
其中local中来定义值 
repeat用来生成 
<#macro repeat count> 
<#local y = "<img src='http://www.jcauto.com.cn/ProConsole/images/star0506.gif' border='0' alt='' width='11' height='11'/>"> 
<#list 1..count as x> 
${y} ${count}/${x}: <#nested> 
</#list> 
</#macro> 
<@repeat count=3>${y?default("?")} ${x?default("?")} ${count?default("?")}</@repeat> 

Ftl变量转换代码 
?number转为数字   
?c转为字符串   
?string转为字符串   
?currency(货币)   
?percent(百分比)   
trim 删除字符串首尾空格 ${“  String ”?trim} 结果为String   
split使用指定的分隔符将一个字符串拆分为一组字符串   
<#list “This|is|split”?split(“|”) as s>   
${s}   
</#list>   
${“strabg”?replace(“ab”,”in”)} 结果为string   
${“string”?contains(“ing”)?string} 结果为true   
注意:布尔值必须转换为字符串才能输出   
${“string”?index_of(“in”) 结果为3  
${“string”?index_of(“ab”) 结果为-1  
length返回字符串的长度 ${“string”?length}结果为6  
lower_case将字符串转为小写   
${“STRING”?lower_case}à结果为string   
upper_case将字符串转为大写   
${“string”?upper_case}à结果为STRING   
ends_with 判断某个字符串是否由某个子串结尾,返回布尔值。   
${“string”?ends_with(“ing”)?string} 返回结果为true   
注意:布尔值必须转换为字符串才能输出   
html 用于将字符串中的<、>、&和“替换为对应得<>":&   
index_of(substring,start)在字符串中查找某个子串,返回找到子串的第一个字符的索引,如果没有找到子串,则返回-1。   
Start参数用于指定从字符串的那个索引处开始搜索,start为数字值。   
如果start大于字符串长度,则start取值等于字符串长度,如果start小于0, 则start取值为   
${‘str’?substring(0)}à结果为str   
${‘str’?substring(0,1)}à结果为s   

2.cap_first 将字符串中的第一个单词的首字母变为大写。   
${‘str’?cap_first}à结果为Str   

3.uncap_first将字符串中的第一个单词的首字母变为小写。   
${‘Str’?cap_first}à结果为str   

4.capitalize将字符串中的所有单词的首字母变为大写   
${‘str’? capitalize}à结果为STR   
date,time,datetime将字符串转换为日期   
例如:   
<#assign date1=”2009-10-12”?date(“yyyy-MM-dd”)>   
<#assign date2=”9:28:20”?time(“HH:mm:ss”)>   
<#assign date3=” 2009-10-12 9:28:20”?time(“HH:mm:ss”)>   
${date1}à结果为2009-10-12  
${date2}à结果为9:28:20  
${date3}à结果为2009-10-12 9:28:20  

?number转为数字 
?c转为字符串 
?string转为字符串 
?currency(货币) 
?percent(百分比) 
trim 删除字符串首尾空格 ${“  String ”?trim} 结果为String 
split使用指定的分隔符将一个字符串拆分为一组字符串 
<#list “This|is|split”?split(“|”) as s> 
${s} 
</#list> 
${“strabg”?replace(“ab”,”in”)} 结果为string 
${“string”?contains(“ing”)?string} 结果为true 
注意:布尔值必须转换为字符串才能输出 
${“string”?index_of(“in”) 结果为3 
${“string”?index_of(“ab”) 结果为-1 
length返回字符串的长度 ${“string”?length}结果为6 
lower_case将字符串转为小写 
${“STRING”?lower_case}à结果为string 
upper_case将字符串转为大写 
${“string”?upper_case}à结果为STRING 
ends_with 判断某个字符串是否由某个子串结尾,返回布尔值。 
${“string”?ends_with(“ing”)?string} 返回结果为true 
注意:布尔值必须转换为字符串才能输出 
html 用于将字符串中的<、>、&和“替换为对应得<>":& 
index_of(substring,start)在字符串中查找某个子串,返回找到子串的第一个字符的索引,如果没有找到子串,则返回-1。 
Start参数用于指定从字符串的那个索引处开始搜索,start为数字值。 
如果start大于字符串长度,则start取值等于字符串长度,如果start小于0, 则start取值为 
${‘str’?substring(0)}à结果为str 
${‘str’?substring(0,1)}à结果为s 

2.cap_first 将字符串中的第一个单词的首字母变为大写。 
${‘str’?cap_first}à结果为Str 

3.uncap_first将字符串中的第一个单词的首字母变为小写。 
${‘Str’?cap_first}à结果为str 

4.capitalize将字符串中的所有单词的首字母变为大写 
${‘str’? capitalize}à结果为STR 

date,time,datetime将字符串转换为日期 
例如: 
<#assign date1=”2009-10-12”?date(“yyyy-MM-dd”)> 
<#assign date2=”9:28:20”?time(“HH:mm:ss”)> 
<#assign date3=” 2009-10-12 9:28:20”?time(“HH:mm:ss”)> 
${date1}à结果为2009-10-12 
${date2}à结果为9:28:20 
${date3}à结果为2009-10-12 9:28:20 

宏定义hash内置函数代码 
Hash的内置函数   
1.hash?keys 返回hash里的所有key,返回结果为sequence   

2.hash?values 返回hash里的所有value,返回结果为sequence   
例如:   
<#assign user={“name”:“hailang”, “sex”:“man”}>   
<#assign keys=user?keys>   
<#list keys as key>   
${key}=${user[key]}   
</#list>  

Hash的内置函数 
1. hash?keys 返回hash里的所有key,返回结果为sequence 

2.hash?values 返回hash里的所有value,返回结果为sequence 
例如: 
<#assign user={“name”:“hailang”, “sex”:“man”}> 
<#assign keys=user?keys> 
<#list keys as key> 
${key}=${user[key]} 
</#list>