freemarker的使用

本文详细介绍Freemarker模板引擎的使用方法,包括配置、标签语法、数据处理技巧及自定义扩展等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

注意事项:
    1、freemarker不支持true和false,需要转换成其他的字符串如,yes,no。例如:${booleanVal?string('yes','no')}
    2、freemarker中的日期格式化支持的是java.sql包下的日期,不支持java.util包下的,util包下的需要格式化,例如:
       ${user.birthday?string('yyyy-MM-dd')}
    3、freemarker中对于null或者不存在的值会报异常,
          ①:我们可以加!号,也可以在!号后面加上一个默认值,通常开发中
              都会加上一个!号,例如:${value!'我是默认值'}或${value!},如果取的是一个对象的属性值,但是该对象不存在,
              则可以对整体加上一个!号,例如:${(value.name)!"默认值"},他会先判断value是否存在,再判断name是否存在,
          ②:另一个方法就是加上一个判断是否为空的标签语句。
    4、单引号和双引号在freemarker中没有区别
    5、判断是否为null或者是否存在的方法:
          ①、<#if value??></#if>,变量名或者集合后面加上连个问号表示判断是否存在
          ②、<#if value?exists><#/if>,使用 ?exists 判断是否存在    
    6、在freemarker中需要用&lt;和&gt;分别代替 < 和 >
    7、在freemarker中可以使用算术运算符和 () 和逻辑运算符
    8、freemarker中函数如果是由多个单词组成的,则多个单词之间用下划线隔开,freemarker中的函数名都是小写字母
    9、freemarker中函数如果不需要参数,则不需要小括号,直接用函数名

一、spring与freemarker整合
    1、配置freemarker模板
      
 <bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
            <property name="templateLoaderPath" value=""/>
            <property name="defaultEncoding" value="utf-8"/>
            <property name="freemarkerSettings">
                <props>
                    <!--设置标签类型 两种:[] 和 <>,[]这种标记解析要快些,但常使用<>-->
                    <prop key="tag_syntax">auto_detect</prop>
                    <!--检查模板更新时间间隔,默认为5秒-->
                    <prop key="template_update_delay">1</prop>
                    <prop key="defaultEncoding">UTF-8</prop>
                    <prop key="url_escaping_charset">UTF-8</prop>
                    <prop key="locale">zh_CN</prop>
                    <prop key="boolean_format">true,false</prop>
                    <!--时间格式化,只针对java.sql.Date, util包下的不行-->
                    <prop key="datetime_format">yyyy-MM-dd HH:mm:ss</prop>
                    <prop key="date_format">yyyy-MM-dd</prop>
                    <prop key="time_format">HH:mm:ss</prop>
                    <prop key="number_format">0.######</prop>
                    <!--去掉空格-->
                    <prop key="whitespace_stripping">true</prop>
                </props>
            </property>
            <!-- 配置自定义的指令 -->
            <property name="freemarkerVariables">
                <map>
                    <entry key="role" value-ref="roleDirectiveModel"/>
                </map>
            </property>
        </bean>

        <!--另外一种配置方式-->
        <!--<bean class="org.springframework.beans.factory.config.PropertiesFactoryBean">
            <property name="location" value="classpath:freemarker.properties"/>
        </bean>-->


        
    2、配置freemarker视图解析器
       
<!--配置freemarker的视图解析器-->
        <bean id="viewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
            <property name="suffix" value=".html"/>
            <property name="prefix" value="/WEB-INF/pages/"/>
            <property name="cache" value="true"/>
            <property name="viewClass" value="org.springframework.web.servlet.view.freemarker.FreeMarkerView"/>
        </bean>


二、freemarker中的标签
    1、<#list userList as user></#list>
        使用例子:
           
<#list userList as user>
                ${user.name} 的生日是:${user.birthday?string('yyyy-MM-dd')}<br>
            </#list>


            as是freemarker中的关键字,userList是集合名称,user是集合中的每一项
    2、<#if expr></#if>
        在该标签中可以使用逻辑运算符 : ||,&&,! 进行多条件判断
    3、<#elseif expr></#elseif>
    4、<#else>
        <#elseif expr/>和<#else/>是用在<#if expr></#if>中的,例如:
           
<#if var<60>
                C
                <#elseif var>90/>
                    A
                <#else/>
                    B
            </#if>


    5、<#assign />:定义变量,例如:
        <#assign var=80/>,定义了一个整形变量,变量名为var
    6、<#switch var><#case var><#break></#switch>,freemarker中的switch支持String类型,用法如下:
           
<#switch var>
                <#case 10>
                    10 <#break/>
                <#case 80>
                    80 <#break/>
                <#default>
                    0
            </#switch>


        注意:<#case var>、<#default>,没有结束标签,也不能在var后加上 / 表示结束,
        
三、list,set和map取值
    1、list
            <#list userList as user>
                ${user.name} 的生日是:${user.birthday?string('yyyy-MM-dd')}<br>
            </#list>
            as是freemarker中的关键字,userList是集合名称,user是集合中的每一项
    2、set
        同list
    3、map
        <#list userMap?keys as key>
            ${key} : ${userMap[key]}
        </#list>
        先取到map集合中的所有键值,?key表示取到map集合中的所有键值,此时key表示map集合中的每一个键值,
        ${userMap[key]}表示取到键值为key的map集合的值,${key}表示获取键值
四、freemarker的内建函数,所有的内建函数前面都要加上 ? ,表示调用该函数
    1、字符串类建函数:+、substring、upper_case、lower_case、index_of、last_index_of、length、replace
        cap_first:首字母大写、ends_width、contains、date、datetime、time:将字符串转换成日期类型(后面需要加上格式化的格式如:yyyy-MM-dd)、
        starts_with、split、trim
    2、list内建函数:sort:排序、reverse:将集合顺序倒过来、size:集合长度、下标取值:list[2]
        first:取第一个值、last:取最后一个值、seq_contains:是不是包含某个序列、seq_index_of:包含的某个序列的位置、
        sort_by:根据list集合里面对象的某一个属性进行排序、chunk:将list集合进行分块,如chunk(4):将一个集合分成4个一块
    3、数字的内建函数:string、x?string("0.##")、round、floor、ceiling
    4、其他内建函数:
        is函数:is_string、is_number、is_method
        has_content函数:判断一个变量等是否有内容,(相当于判断是否不存在或是否为空)
        eval求值函数(不常用):对 ?eval 前面的表达式进行求值
    5、string(format):格式化,如日期格式化或者boolean类型格式化
    6、exist:判断变量、对象或者集合是否存在
    
五、freemarker自定义函数
    freemarker自定义函数需要实现TemplateMethodModelEx接口,实现exec方法。
    freemarker自定义函数时需要先将参数转换为freemarker的数据类型,然后转换为Java的数据类型,不然会报错。
    1、编写类实现TemplateMethodModelEx接口,实现exec方法,exec方法接收一个集合,如下例子:
        public class SortMethod implements TemplateMethodModelEx {
            public Object exec(List list) throws TemplateModelException {
                SimpleSequence sequence = (SimpleSequence) list.get(0);
                List<BigDecimal> list1 = sequence.toList();
                Collections.sort(list1, new Comparator<BigDecimal>() {
                    public int compare(BigDecimal o1, BigDecimal o2) {
                        return o1.intValue()-o2.intValue();
                    }
                });
                return list1;
            }
        }
    2、将函数添加到model中,如下代码:
        mv.addObject("sort_int",new SortMethod());  sort_int 表示函数名,这样就可以在HTML中使用了
    3、使用函数,如下代码:
        <#assign list=[5,6,2,3,7,9,8,4,0,1]/>
        <#list sort_int(list) as item>
            ${item_index} : ${item}<br>
        </#list>
        其中,_index表示取下标
六、freemarker自定义指令
    freemarker自带指定使用 <# 开始,自定义指令使用 <@ 开始,自定义指令使用
    freemarker自定义指令中,入参使用key-value形式,多个key-value之间使用空格隔开,多个返回值之间使用逗号隔开,
    key-value与返回值之间使用分号 ;隔开,出参需要使用freemarker的数据类型,所以需要把出参转换为freemarker的数据类型
    freemarker自定义指令需要实现TemplateDirectiveModel接口,实现execute方法,
    1、编写类实现TemplateDirectiveModel接口,实现execute方法,如下:
        @Service
        public class RoleDirectiveModel implements TemplateDirectiveModel {
            /**
             *
             * @param environment:环境变量
             * @param map:指令参数
             * @param templateModels:循环变量(出参)
             * @param templateDirectiveBody:指令内容
             * @throws TemplateException
             * @throws IOException
             */
            public void execute(Environment environment, Map map, TemplateModel[] templateModels,
                                TemplateDirectiveBody templateDirectiveBody) throws
                    TemplateException, IOException {
                /*需要转换成freemarker的数据类型*/
                TemplateScalarModel user= (TemplateScalarModel) map.get("user");
                TemplateScalarModel role= (TemplateScalarModel) map.get("role");
                if("12345".equals(user.getAsString()) && "admin".equals(role.getAsString())){
                    /*需要转换成freemarker的数据类型*/
                    templateModels[0]=TemplateBooleanModel.TRUE;
                }
                List<String> otherRights=new ArrayList<String>();
                otherRights.add("add");
                otherRights.add("delete");
                otherRights.add("update");
                /*需要转换成freemarker的数据类型*/
                templateModels[1]=new SimpleSequence(otherRights);
                /*将指令中的内容打印输出*/
                templateDirectiveBody.render(environment.getOut());
            }
        }
    2、将定义好的指令添加到配置freemarker模板引擎的bean中,配置在freemarkerVariables下,key表示指定名称,value-ref表示指令的逻辑对应的bean类,如下:
        <property name="freemarkerVariables">
            <map>
                <entry key="role" value-ref="roleDirectiveModel"/>
            </map>
        </property>
    3、使用自定义指令
        <@role user="12345" role="admin";result1,result2>
            <#if result1>
                has privilege admin
            </#if>
            <#list result2 as item>
                ${item}<br/>
            </#list>
        </@role>
七、freemarker定义宏指令 <#macro></#macor>
    1、使用 <#macro name param1 param2 paramN></#macro> 定义宏指令,其中name是定义的指令名称,param是参数,没有参数,也可以有多个参数
    2、<#macor></#macro>中的内容会在调用相应的定义的标签时输出,<#macor></#macro>标签体中定义的内容相当于一个输出模板
    3、定义多个参数时,可以如下定义:<#macro name param1 param2 paramN otherParam...></#macro>,其中 ... 表示多个参数
    4、也可以给参数设置默认值,例如:<#macro name param1 param2='我是默认值'></#macro>
    5、使用 <@name param1=XXX param2=XXX/> 来使用来调用指令,freemarker指令中的参数可以是整形(不加引号),数组或者集合(使用中括号),字符串(加引号)
       不同于HTML标签中的属性都是字符串。
    6、<#nested param1,param2/>常用在<#macro></#macor>中用于个性化处理,<#nested/> 的参数使用逗号 , 隔开,如下例子:
        <#macro test param1 param2>
            ${param1+param2},${param2}<br>
            <#nested param1,"nested"/>
        </#macro>
        <@test param1=1 param2=2;var1,var2>
            ${var1},${var2}
        </@test>
        其中var1、var2代表<#nested/>中的两个参数,也是使用逗号 , 隔开,与<#macro >中定义的参数使用分号 ; 隔开。注意:<#nested/> 不能写成<#nested></#nested>
八、<#function>定义函数
    1、使用 <#function name param1 param2></#function>分装一个函数,name表示函数名称,param表示参数,如下例子:
            <#function name param1 param2>
                <#return param1+param2>
            </#function>
            该例子表示两个数的加法运算,其中<#return expr> 表示返回函数的运算结果,调用函数时需要使用 ${name(param1,param2)} 形式,跟取值差不多。
FreeMarker官方参考文档总共有四份,它们分别是  Designer's Guide(网上已有翻译,主要从FreeMarker 的概念上介绍)  Programmer's Guide(本文档所以翻译的部分,主要从框架的设计方面介绍)  XML Processing Guide(对XML数据模型处理的介绍)  Reference(FreeMarker 的参考文档,语言使用介绍) 中文翻译之所以选择 Programmer's Guide 是因为个人觉得该部分对如何实现 FreeMarker 进行了比较深入的阐述。有助于读者很好的了解其运作机制,以及去理解其他 模板引擎(如Velocity)的工作机理。 注:由于原文档部分内容直译可能难于被读者理解,所以有些地方采用意译为主,因此在翻译用词上 难 免 可 能 会 有 出 入 , 大 家 对 翻 译 的 内 容 有 任 何 意 见 都 可 以 给 我 直 接 发 邮 件 告 知 motomagice@yahoo.com.cn 目录 前言.........................................................................3 一、快速入门..............................................................4 1.1、创建配置实例..............................................................................4 1.2、创建数据模型(Data Model) ..........................................................4 1.3、获取模版(template) ..................................................................5 1.4、把模版与数据模型合并...................................................................6 1.5、完整的代码 ................................................................................6 二、数据模型(Data Model) ..........................................7 2.1、基础类型...................................................................................7 2.2、Scalar类型(单值对应的Data Model)...............................................8 2.3、容器类型...................................................................................8 2.4、方法变量...................................................................................9 2.5、转换器变量 .............................................................................. 10 2.6、节点变量................................................................................. 12 2.7、对象包裹................................................................................. 12 三、配置(Configuration)........................................... 15 3.1、基础....................................................................................... 15 3.2、共享变量................................................................................. 15 3.3、配置参数................................................................................. 16 3.4、加载模板................................................................................. 17 3.5、异常处理................................................................................. 19 四、其它说明............................................................ 20 4.1、变量....................................................................................... 20 4.2、字符编码................................................................................. 20 4.3、多线程.................................................................................... 21 4.5、Bean 包裹................................................................................ 21
### 使用FreeMarker模板引擎进行Java开发 #### 配置环境 为了使用FreeMarker,在项目中需引入依赖库。对于Maven项目,可以在`pom.xml`文件中加入如下配置: ```xml <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.31</version> </dependency> ``` #### 初始化Configuration对象 创建并初始化`Configuration`实例来设置模板路径和其他参数。 ```java import freemarker.template.Configuration; import freemarker.template.Template; public class TemplateEngine { private Configuration cfg; public TemplateEngine() throws Exception { // 创建一个新的配置实例 cfg = new Configuration(Configuration.VERSION_2_3_30); // 设置模板加载器,默认从类路径下读取模板文件 cfg.setClassForTemplateLoading(this.getClass(), "/templates/"); cfg.setDefaultEncoding("UTF-8"); cfg.setLocale(Locale.US); cfg.setOutputFormat(HtmlMarkupOutputFormat.INSTANCE); } } ``` #### 加载模板与数据模型处理 通过`cfg.getTemplate()`方法获取指定名称的模板,并准备要传递给模板的数据模型。 ```java Map<String, Object> dataModel = Maps.newHashMap(); dataModel.put("title", "Hello World!"); dataModel.put("message", "Welcome to FreeMarker!"); // 获取名为 'index.html' 的模板 Template temp = cfg.getTemplate("index.html"); Writer out = new OutputStreamWriter(System.out); try { // 将数据渲染到输出流 temp.process(dataModel, out); } finally { out.flush(); } ``` 当访问不存在变量或null值时,FreeMarker会将其视为错误终止执行[^3]。因此建议开发者在编写模板前充分考虑这些情况,可以利用内置函数如`${variable!default_value}`为可能为空的对象提供默认显示内容。 #### 处理HTML资源位置约定优于配置原则 按照惯例而非配置的方式工作意味着框架能够自动识别位于特定目录下的`.html`文档作为视图页面而无需额外设定。例如,如果定义了常量`DEFAULT_PREFIX="classpath:/templates/"` 和 `DEFAULT_SUFFIX=".html"` ,那么只需编辑resources/templates 文件夹内的 HTML 文件即可让Thymeleaf 自动呈现它们[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值