`

Freemarker的常用技巧总结

 
阅读更多

1,截取字符串

有的时候我们在页面中不需要显示那么长的字符串,比如新闻标题,这样用下面的例子就可以自定义显示的长度

< lt. <= lte. > gt. >= gte

<#if jstbqkVO.gzdd?length lt 8>
<a href>${jstbqkVO.gzdd?default("")}</a>
<#else>
<a href title="${jstbqkVO.gzdd}">${jstbqkVO.gzdd[0..3]?default("")}...</a>
</#if>

意思就是如果这个字符串的长度小于8,那么就正常显示,反之则取4位

2.连接字符串

${"Hello," + user + "!"} //输出结果为:hello,gs!

3,日期格式和boolean 类型,转化为string类型

例子2:

${lastUpdate?string("yyyy-MM-dd HH:mm:ss zzzz")}

${lastUpdate?string("EEE,MMM d, ''yy")}

${.................("EEEE,MMM dd,yyyy, hh:mm:ss a '('zzz')'")}

输出结果如下:

2003-04-08 21:24:44 Pacific Daylight Time

Tue,Apr 8,'03

Tuesday,April 08,2003,09:24:44 PM (PDT)

例子3:

<#assign foo=true/>

${foo?string("yes","no")} //输出结果:yes

4,排序:

1.升序.sort_by()

<#list list?sort_by("字段") as x>
</#list>

2.降序.sort_by()?reverse

<#list list?sort_by("字段")?reverse as x>
</#list>

5去空格:

${xx?trim}

6数值精度控制

mX:小数部分最小X位。

MX:小数部分最大X位。

例子:

<#assign x=2.582/>

<#assign y=4/>

#{x; M2} //2.58

#{y; M2} //4

#{x; m1M2} //2.58

#{y; m1M2} //4.0

7特殊字符串的转义

\":双引号 \\:反斜杠 \r:回车 \b:退格键

\':单引号 \n:换行 \t:Tab \f:Form feed

\l:< \g:> \a:& \{:{

\xCode:直接通过4位的十六进制数来指定Unicode码

,输出改Unicode对应的字符。

8.顶层变量

* 所谓顶层变量就是直接放在数据模型中的值。

Map root = new HashMap();

root.put("name","yeeku"); //name是一个顶层对象

* 对于顶层变量,直接使用${variableName}来输出变量值

9.集合连接运算符

* 集合连接运算是将两个集合连接成一个新的集合,连接集合的运算符是'+'.

<#list ["一","二","三"] + ["四","五","六"] as x>

${x}

</#list>

//输出结果如下:

一二三四五六

10 算术运算符

* 取整运算

<#assign x=5>

${(x/2)?>int} //2

${1.1?int} //1

${1.999?int} //1

${-1.1?int} //-1

11 比较运算符

=(==) :判断两个值是否相等

!= :............不相等

>(gt) :判断左边是否大于右边

>=(gte) :.....

<(lt) :.....

<=(lte) :.....

12 逻辑运算符

* 逻辑运算符只能作用于布尔值,否则将产生错误.

逻辑与:&&

逻辑或:||

逻辑非:!

13 内置函数

html:字符串中所有的特殊HTML字符都需要用实体引用来代替(比如<代替&lt;)
cap_first:字符串的第一个字母变为大写形式
lower_case:字符串的小写形式
upper_case:字符串的大写形式
trim:去掉字符串首尾的空格

序列使用的内建函数:
size:序列中元素的个数
数字使用的内建函数:
int:数字的整数部分(比如-1.9?int就是-1)9>.空值运算符

length:字符串的长度

string :把其他格式的数据,转化为string类型

例:

${test?html}
${test?upper_case?html}

假设字符串test存储”Tom & Jerry”,那么输出为:

Tom &amp; Jerry
TOM &amp; JERRY

${seasons?size}
${seasons[1]?cap_first}

${"horse"?cap_first}

假设seasons存储了序列"winter", "spring", "summer", "autumn",那么上面的输出将会是:

4
Spring
Horse

14.运算符优先级

* 推荐使用括号来决定运算优先级.

1>.一元运算符: !

2>.内建函数 : ?

3>.乘除法 : *,/,%

4>.加减法 : +,-

5>.比较 : <,>,<=,>=(lt,lte,gt,gte)

6>.相等 : ==(=),!=

7>.逻辑与 : &&

8>.逻辑或 : ||

9>.数字范围 : ..

15,freemarker判断返回值是否为空,null的方法

对于null,或者miss value,freemarker会报错
!:default value operator,语法结构为:unsafe_expr!default_expr,比如 ${mouse!"No mouse."} 当mouse不存在时,返回default value;
(product.color)!"red" 这种方式,能够处理product或者color为miss value的情况;
而product.color!"red"将只处理color为miss value的情况
??: Missing value test operator ,测试是否为missing value
unsafe_expr?? :product.color??将只测试color是否为null
(unsafe_expr)??:(product.color)??将测试product和color是否存在null
?exists:旧版本的用法
比如:<#if mouse??>
Mouse found
<#else>
No mouse found
</#if>
Creating mouse...
<#assign mouse = "Jerry">
<#if mouse??>
Mouse found
<#else>
No mouse found
</#if>

FreeMarker的常用指令

1>.if指令

<#if condifition>

...

<#elseif condifition>

...

<#else>

...

</#if>

2>.switch、case、default、break指令

<#switch value>

<#case refValue1>

...

<#break>

<#case refValue2>

...

<#break>

<#default>

...

</#switch>

3>.list、break指令

<#list sequence as item>

...

</#list>

* item_index :当前变量的索引值.

* item_has_next :是否存在下一个对象.

例子:

<#list ["星期一","星期二","星期三","星期四","星期五","星期六"] as x>

${x_index + 1}.${x}

<#if x_has_next>,</#if>

<#if x="星期四"><#break></#if>

</#list>

输出结果:

1.星期一,

2.星期二,

3.星期三,

4.兴趣四,

4>.include指令

:用于指定包含指定页面.

<#include filename [options]>

* filename: 该参数指定被包含的模板文件.

* options : 该参数可以被省略,指定包含时的选项,包含encoding和parase两个选项.

5>.import指令

<#import path as mapObject>

* path :指定要被导入的模板文件.

* mapObject :是一个Map对象.

意思:将path路径中的变量都放在mapObject中.

例子:<#import "/lib/common.ftl" as com>

6>.noparser指令

noparse指令指定FreeMarker不处理该指令里包含的内容.

<#noparse>...</#noparse>

7>.escape指令

* escape:该指令导致body区的插值都会被自动加上escape表达式.

* escape指令解析模板时起作用,而不是在运行时起作用.

* escape指令也嵌套使用,子escape继承父escape的规则.

* 如果需要指定某些插值无需添加escape表达式,则应该使用noescape指令.

<#escape identifier as expression>

...

<#noescape>...</#noescape>

...

</#escape>

8>.assign指令

* 它用于为该模板页面创建或替换一个(顶层)或多个变量.

第一种用法:<#assign name="value" [in namespacehash]>

in子句用于将创建的name变量放入namespacehash命名空间中.

第二种用法:<#assign name1=value1 name2=value2 ... nameN=valueN [in namespacehash]>

第三种用法: 是指将assign指令的内容赋值给name变量.

<#assign name [in namespacehash]>

capture this

</#assign>

例子:

<#assign x>

<#list ["一","二","三"] as n>

${n}

</#list>

</#assign>

${x}

补充.global指令,全局变量赋值

9>.setting指令

:该指令用于设置FreeMarker的运行环境.

<#setting name=value>

name的取值范围如下:

locale:该指令指定该模板所使用的国家语言/语言选项.

number_format:该指令指定格式化输出数字的选项.

boolean_format:该指令指令两个布尔值的语法格式,默认值是"false".

date_format、time_format、datetime_format:格式化输出日期的格式.

time_zone: 设置格式化输出日期时所使用的时区.

10>.macro、nested、return指令

宏和变换器变量是两种不同类型的用户自定义指令,他们的区别是:

宏可以在模板中用macro指令来定义
变换器是在模板外由程序定义

1、宏:和某个变量关联的模板片段,以便在模板中通过用户自定义指令使用该变量
1-1、基本用法:
例如:
<#macro greet>
<font size="+2"> Hello JOE!</font>
</#macro>


使用时:
<@greet></@greet>
如果没有体内容也可以用
<@greet />

1-2、变量:

1)、可以在宏定义之后定义参数,宏参数是局部变量,只在宏定义中有效。如:

<#macro greet person>
<font size="+2"> Hello ${person}!</font>
</#macro>
使用时:
<@greet person="emma"> and <@greet person="LEO">
输出为:
<font size="+2"> Hello emma!</font>
<font size="+2"> Hello LEO!</font>

注意:宏的参数是FTL表达式,所以,person=emma和上面的例子中具有不同的意义,这意味着将变量emma的值传给person,这个值可能是任意一种数据类型,甚至是一个复杂的表达式。

宏可以有多个参数,使用时参数的次序是无关的,但是只能使用宏中定义的参数,并且对所有参数赋值。如:
<#macro greet person color>
<font size="+2" color="${color}"> Hello ${person}!</font>
</#macro>

使用时:
<@greet color="black" person="emma" />正确
<@greet person="emma" />错误,color没有赋值,此时,如果在定义宏时为color定义缺省值<#macro greet person color="black">这样的话,这个使用方法就是正确的。
<@greet color="black" person="emma" bgcolor="yellow" />错误,宏greet定义中未指定bgcolor这个参数

11>自定义函数的使用

. 编写函数

package com.freemarker.test;     import java.text.SimpleDateFormat;   import java.util.Date;   import java.util.List;   import freemarker.template.TemplateMethodModel;  import freemarker.template.TemplateModelException;       public class SqlGetSysdateMethod implements TemplateMethodModel  {        public Object exec( List args ) throws TemplateModelException   {   //得到函数第一个参数,得到的字符串两头会有引号,所以replace   String datePattern=(args.get( 0 ).toString()).replace( , );      Date date = new Date();   SimpleDateFormat sdf =new SimpleDateFormat(datePattern);      return sdf.format( date );   }    }

2.注册与使用

   有两种方式:

   (1).在模板文件中注册,在模板中使用

<#assign getSysdate= packagecom.freemarker.test.SqlGetSysdateMethod?new()>

<#assign curdate=getSysdate(yyyy-MM-ddt)/>
(2).处理模板文件时注册关键代码:

Map<String,Object> root=new HashMap<String, Object>();
root.put(getSysdate, new StringLengthMethod());
Configuration config=new Configuration();
File file=new File(templatePath);
//并加载模板文件
config.setDirectoryForTemplateLoading(file);
//设置包装器,并将对象包装为数据模型
config.setObjectWrapper(new DefaultObjectWrapper());

//获取模板,并设置编码方式,这个编码必须要与页面中的编码格式一致
Template template=config.getTemplate(templateName,templateEncoding);
//合并数据模型与模板
template.process(root, out);

12>使用宏写一个简单的分页实例

<#macropaginationtotalCountpageSize>

<#--声明一个函数transform转换uri,在新的uri上pager_offset参数-->

<#assigntransform="util.TransformURI"?new()>

<#--声明一个函数,得到当前页码-->

<#assignpagerOffset="util.PagerOffset"?new()>

<#--声明一个函数,根据传入的totalCount,pageSize得到总页数-->

<#assignpagerCount="util.PageCount"?new()>

<#assignpageCount=pagerCount(totalCount,pageSize)>

<#--得到当前的URI和请求参数,得到当前的页码-->

<#ifrequest.queryString?exists>

<#assignuri=request.requestURI+"?"+request.queryString>

<#assignpageIndex=pagerOffset(uri)>

<#assignnew_uri=transform(uri)>

<#else>

<#assignuri=request.requestURI>

<#assignpageIndex=pagerOffset(uri)>

<#assignnew_uri=transform(uri)>

</#if>

<#if(pageIndex>pageCount)>

<#assignpageIndex=pageCount>

</#if>

<#if(pageIndex>1)>

<ahref="${new_uri+1}"title="首页">&lt;&lt;</a>

</#if>

<#--如果前面页数过多,显示"..."-->

<#if(pageIndex>5)>

<#assignprevPages=pageIndex-9>

<#ifprevPageslt1>

<#assignprevPages=1>

</#if>

<#assignstart=pageIndex-4>

<ahref="${new_uri+prevPages}"title="向前5页">...</a>

<#else>

<#assignstart=1>

</#if>

<#--显示当前页附近的页-->

<#assignend=pageIndex+4>

<#if(end>pageCount)>

<#assignend=pageCount>

</#if>

<#liststart..endasindex>

<#ifpageIndex==index>

<b>${index}</b>

<#else>

<ahref="${new_uri+index}">${index}</a>

</#if>

</#list>

<#--如果后面页数过多,显示"...":-->

<#if(endltpageCount)>

<#assignendend=end+5>

<#if(end>pageCount)>

<#assignend=pageCount>

</#if>

<ahref="${new_uri+end}"title="向后5页">...</a>

</#if>

<#--显示"下一页":-->

<#if(pageIndexltpageCount)>

<ahref="${new_uri+pageCount}"title="末页">&gt;&gt;</a>

</#if>

</#macro>

自定义了三个方法:

PageCount.java

packageutil;

importjava.util.List;

importfreemarker.template.TemplateMethodModel;

importfreemarker.template.TemplateModelException;

/**

*根据传入的参数,计算出所有的页数

*@authorlegolas

*/

publicclassPageCountimplementsTemplateMethodModel{

@Override

publicObjectexec(Listargs)throwsTemplateModelException{

IntegertotalCount=0;

IntegerpageSize=0;

try{

totalCount=Integer.parseInt((String)args.get(0));

pageSize=Integer.parseInt((String)args.get(1));

}catch(NumberFormatExceptione){

thrownewTemplateModelException("请输入正确的总记录数和页面记录数");

}

IntegerpageCount=totalCount/pageSize

+(totalCount%pageSize==0?0:1);

returnpageCount;

}

}

TransformURI.java

packageutil;

importjava.util.List;

importfreemarker.template.TemplateMethodModel;

importfreemarker.template.TemplateModelException;

/**

*根据传入的uri,在uri后面加上分页参数

*@authorlegolas

*

*/

publicclassTransformURIimplementsTemplateMethodModel{

@Override

publicObjectexec(Listargs)throwsTemplateModelException{

Stringuri=(String)args.get(0);

intn=uri.lastIndexOf("?");

if(n==-1){

returnuri+"?pager_offset=";

}

if(uri.lastIndexOf("?pager_offset")!=-1){

uri=uri.substring(0,uri.lastIndexOf("=")+1);

returnuri;

}

StringqueryString=uri.substring(n+1,uri.length());

Stringsuburi=uri.substring(0,n+1);

String[]strings=queryString.split("&");

for(inti=0;i<strings.length;i++){

if(strings[i].startsWith("pager_offset")){

continue;

}

suburi+=strings[i];

suburi+="&pager_offset=";

}

returnsuburi;

}

}

PagerOffset.java

packageutil;

importjava.util.List;

importfreemarker.template.TemplateMethodModel;

importfreemarker.template.TemplateModelException;

/**

*得到当前的页码

*@authorlegolas

*

*/

publicclassPagerOffsetimplementsTemplateMethodModel{

@Override

publicObjectexec(Listargs)throwsTemplateModelException{

Stringuri=(String)args.get(0);

String[]string=uri.split("pager_offset=");

if(string.length==1){

return1;

}else{

Integerpager_offset=1;

try{

pager_offset=Integer.parseInt(string[1]);

}catch(NumberFormatExceptione){

pager_offset=1;

}

returnpager_offset;

}

}

}

7>.关于在FreeMarker中使用Struts2标签

* FreeMarker作为视图组件是由Servlet负责加载该模板,并使用数据模型填充该模板,并且将填充后

的标准HTML响应输出给浏览者.

* 在Struts2框架的支持下,Struts2框架充当了之前的Servlet角色.

* 为了使所有的用户请求都经过Struts2框架处理,我们将所有的FreeMarker模板放在WEB-INF/ftl路径下.

* 放在WEB-INF/路径下可以提供更好的安全性,因为Web容器会保证浏览者无法访问到WEB-INF/路径下的资源.

8>.解析模板中的变量

* Struts2解析FreeMarker模板中变量的顺序如下:

1>.FreeMarker模板内建的变量

2>.ValueStack中的变量.

3>.ActionContext中的变量.

4>.HttpServletRequest范围的属性.

5>.HttpSession范围的属性.

6>.ServletContext范围的属性.

* FreeMarker模板的内建变量如下:

stack:代表ValueStack本身,可这样访问其中变量:${stack.findString('ognl expr')}

action:代表刚刚执行过的Action实例.

response:代表HttpServletResponse实例.

request:代表HttpServletRequest实例.

res:代表HttpServletRequest实例.

session:代表HttpSession实例.

application:代表ServletContext实例.

base:代表用户请求的上下文路径.

9>.访问Servlet/JSp范围对象

1.访问Application范围内的属性.

<#if Application.attributeName?exists>

${Application.attributeName}

</#if>

使用struts2标签输出:<@s.property value="%{Application.attributeName}"/>

2.访问HttpServletRequest中的参数

<#if Parameter.parameter?exists>

${Parameter.parameter}

</#if>

分享到:
评论

相关推荐

    freemarker 中午手册

    ### Freemarker 中文手册知识点详解 #### 一、Freemarker 概述 - **定义与功能**:Freemarker 是一款用纯 Java 编写的...通过上述知识点的介绍,希望能够帮助读者更好地理解和掌握 Freemarker 的基本概念和使用技巧。

    SSM框架freemarker的demo

    总结,这个"SSM框架freemarker的demo"涵盖了如何在Java Web项目中整合SpringMVC、MyBatis以及FreeMarker,通过模板引擎FreeMarker实现了数据和视图的分离,提高了代码的可维护性。通过学习和实践这个示例,开发者...

    springboot-integration-examples,springboot与其他常用技术的集成.zip

    总结,"springboot-integration-examples"是一个非常实用的学习资源,无论你是初识SpringBoot,还是希望进一步提升SpringBoot的使用技巧,都能从中受益匪浅。通过深入研究和实践,你将能够熟练掌握SpringBoot与各类...

    freemaker 中文开发手册

    本章节将详细介绍Freemaker的基础概念、核心指令以及一些实用技巧,帮助开发者更好地理解和应用这一工具。 #### 二、核心概念与指令 ##### 1. 核心概念 - **Sequence (序列)**:对应于Java中的List或数组等非键值...

    基于springboot的成人教育教务系统源码数据库.zip

    在实际开发中,SpringBoot可以集成MyBatis或JPA进行数据持久化,使用Thymeleaf或Freemarker进行视图渲染,利用RabbitMQ或Kafka实现消息队列,使用Elasticsearch进行全文搜索,利用Docker进行容器化部署,提高系统的...

    Java Web应用(张孝祥ppt格式课件)

    1. **Tomcat中的类装载器**:Tomcat作为Java Web应用的常用服务器,其类装载器负责加载应用中的类。通过context.xml配置,可以定义资源,如在示例中配置了邮件服务的资源,使得Servlet可以通过JNDI查找并获取这些...

    Struts 2权威指南源码

    6. **拦截器**:介绍Struts 2的拦截器机制,如何自定义拦截器,以及常用拦截器如Validation、Exception Handling的应用。 7. **表单和数据绑定**:讲解Struts 2中的表单元素,以及如何进行数据绑定,使用OGNL...

    IntelliJ-IDEA13基础教程

    #### 常用技巧 - **Debug 跟踪条件变量**:利用调试器跟踪变量的变化情况。 - **Live Template 使用**:创建和使用 Live Templates 快速生成代码片段。 - **代码分析**:自动检测代码中的潜在问题和改进点。 - **...

    struts2 学习重点笔记

    ### Struts2 学习重点知识点总结 #### 一、Struts2 概念与架构 **1.1 Struts2 简介** - **定义**:Struts2 是 Apache 组织提供的一个基于 MVC 架构模式的开源 Web 应用框架。 - **核心**:Struts2 的核心其实是 ...

    SSM框架的思维导图

    SSM框架是Java Web开发中常用的三大组件——Spring、SpringMVC和Mybatis的集成,它们共同构建了一个灵活且强大的后端服务架构。这五个思维导图分别详细描绘了SSM框架的各个组成部分以及它们之间的关系,对于理解和...

    SSH框架整合

    总结来说,SSH框架整合是Java Web开发中的常用实践,它利用Spring的全面管理、Struts2的流程控制和Hibernate的ORM能力,构建出高效、解耦的Web应用。掌握SSH的整合技巧,对于提升Java Web开发效率和项目质量具有重要...

    ticket-manage票务疫情springboot+mybatis

    它集成了大量常用的第三方库,如数据访问、安全、缓存等,使得开发者可以快速搭建应用。在本项目中,SpringBoot作为基础框架,提供了自动配置、内嵌Tomcat服务器以及各种starter模块,使得开发者能够专注于业务逻辑...

    java学习网站大全

    根据提供的标题、描述以及部分内容,我们可以总结出一系列与Java学习相关的知识点及资源。这些资源涵盖了从基础到进阶的不同层次,对于初学者或是想要深化Java技能的人来说都非常有用。 ### Java学习资源概览 ####...

    三大框架的执行原理

    SSH,即Struts2、Hibernate和Spring,是Java Web开发中常用的三大框架。它们各自有着不同的职责,共同构建了一个高效、松耦合的应用架构。 **Struts2执行原理:** Struts2是一个MVC(Model-View-Controller)框架,...

    jfreechart,报表,struts

    在"压缩包子文件的文件名称列表"中提到的"报表及struts2中常用",可能包含了一些常见的Action类、JSP页面、配置文件以及相关的资源文件。通过分析这些文件,开发者可以了解如何在实际项目中整合JFreeChart和Struts2...

    spring_boot_tutorial.pdf_springboot_spring_源码

    它集成了大量常用的第三方库配置,如数据库、邮件服务、缓存、消息队列等,可以极大地提高开发效率。 二、Spring Boot核心特性 1. 自动配置:Spring Boot会根据项目依赖自动配置相关组件,比如引入了Spring Data ...

    Structs2 标签库详解

    CNNS可能是指某个特定的项目或系统,"小收集"可能是该项目中的一些技巧或经验总结,例如如何优化Structs2的性能,或者解决某些常见的问题。具体细节可能需要查看"CNNS登陆以及小收集.txt"文件。 总的来说,Structs...

    SpringBoot学习大纲.zip

    - 可能包含各种开发工具、插件、IDE集成、调试技巧等,提高开发效率。 8. **部分疑惑解答.txt** - 提供了对学习中遇到疑问的解答,针对特定问题提供解决方案。 9. **spring-boot配置.txt** - 对Spring Boot的...

    使用JSP技术构建电子商务应用系统-从入门到提高

    总结,本教程将带领读者从零开始,逐步掌握使用JSP构建电子商务应用的全过程,从基本概念到高级技巧,从设计用户界面到实现业务逻辑,再到性能优化和安全防范,全面涵盖JSP在电商系统中的应用。通过阅读提供的PDF...

Global site tag (gtag.js) - Google Analytics