zoukankan      html  css  js  c++  java
  • Freemarker语法

    FreeMarker 是一款 模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具。 它不是面向最终用户的,而是一个Java类库,是一款程序员可以嵌入他们所开发产品的组件。

    特点

    1. 轻量级模版引擎,不需要Servlet环境就可以很轻松的嵌入到应用程序中

    2. 能生成各种文本,如html,xml,java,等

    3. 入门简单,它是用java编写的,很多语法和java相似

    freemarker模板文件(*.ftl)的基本组成部分:

    1. 文本:直接输出的内容部分

    2. 注释:会被FreeMarker直接忽略, 更不会在输出内容中显示,格式为<#--  注释内容  -->

    3. 取值(插值):这部分的输出会被计算的值来替换,格式为   ${数据模型}   或   #{数据模型}(这种风格已经不建议使用)

    4. ftl指令:Freemarker指令,类似于HTML标签,但是它们却是给FreeMarker的指示, 而且不会打印在输出内容中( 至于什么是内建指令,什么是自定义指令   下面会叙述到)

      • 内建指令:开始标签:<#directivename parameter>       结束标签:</#directivename>      空标签:<#directivename parameter/>   
      • 自定义指令:开始标签:<@directivename parameter>       结束标签:</@directivename>      空标签:<@directivename parameter/> 
    文本, 插值, FTL 标签, 注释
    <html> <head>  <title>Welcome!</title> </head> <body> <#-- Greet the user with his/her name --> <h1>Welcome ${user}!</h1> <p>We have these animals: <ul> <#list animals as animal> <li>${animal.name} for ${animal.price} Euros </#list> </ul> </body> </html>

     注意:

    • FTL是区分大小写的。 list 是指令的名称而 List 就不是。类似地 ${name} 和 ${Name} 或 ${NAME} 也是不同的。
    • 请注意非常重要的一点: 插值 仅仅可以在 文本 中使用。
    • FTL 标签 不可以在其他 FTL 标签 和 插值中使用。比如, 这样做是 错误 的: <#if <#include 'foo'>='bar'>...</#if>
    • 注释 可以放在 FTL 标签 和 插值中。
    <h1>Welcome ${user <#-- The name of user -->}!</h1>
    <p>We have these animals:
    <ul>
    <#list <#-- some comment... --> animals as <#-- again... --> animal>

    工作原理:(借用网上的图片)                 

    语法及使用方法:

    数据类型

    和java不同,FreeMarker不需要定义变量的类型,直接赋值即可。

    字符串: value = "xxxx" 。如果有特殊字符 string = r"xxxx" 。单引号和双引号是一样的。

    数值:value = 1.2。数值可以直接等于,但是不能用科学计数法。

    布尔值:true or  false。

    List集合:list = [1,2,3] ; list=[1..100] 表示 1 到 100 的集合,反之亦然。

    Map集合:map = {"key" : "value" , "key2" : "value2"},key 必须是字符串哦!

    实体类:和EL表达式差不多,直接点出来。

    字符串操作

    字符串连接:可以直接嵌套${"hello , ${name}"} ; 也可以用加号${"hello , " + name}

    字符串截取:string[index]。index 可以是一个值,也可以是形如 0..2 表示下标从0开始,到下标为2结束。一共是三个数。

    比较运算符

    == (等于),!= (不等于),gt(大于),gte(大于或者等于),lt(小于),lte(小于或者等于)。不建议用 >,<  可能会报错!

    一般和 if 配合使用

    变量空判断

     !    指定丢失变量的默认值;一般配置变量输出使用。 对表达式自动检查 null 值和空字符串

    Invoice Date: ${(customer.invoice.date)!}
    //如果 customer、invoice 或者 date 中有一个为空值或空字符串,你只会得到标签:
    Invoice Date:
    
    Invoice Date: ${(customer.invoice.date)!'No Invoice Available'}
    //如果所有值丢失,你会得到:
    Invoice Date: No Invoice Available

    ??    判断变量是否存在。一般配合if使用 <#if value??></#if>

    支持 JSON

    FreeMarker 内置 JSON 支持。 比方说你有以下的 JSON 存储到变量命名 user 的字符串中。

    { 'firstName': 'John', 'lastName': 'Smith', 'age': 25, 'address': { 'streetAddress': '21 2nd Street', 'city': 'New York', 'state': 'NY', 'postalCode': 10021 }}

    使用 ?eval 将从字符串转换为一个 JSON 对象,然后像其他数据一样在表达式中使用。

    <#assign user = user?eval>
    User: ${user.firstName}, ${user.address.city}

     取值(插值)指令及适用类型:

     ${var}  适用类型:java中常用的八大基本类型以及我们的String引用类型,但是,freemarker中boolean类型显示时true==yes  false==no

    //在后台文件中定义变量
    String strVar = "世界你好";
    int intVar = 10;
    boolean booVar = true;
    //在页面中获取变量:
    <font color="red"> ${strVar} </font><br>            //String获取
    <font color="red"> ${intVar} </font><br>           //int获取
    <font color="red"> ${booVar?string("yes","no")} </font>  //boolean获取
    //展示结果:String获取:世界你好  int获取:10  boolean获取:yes

     ${var!}   适用类型:对 null 或者不存在的对象进行取值,可以设置默认值,例:${var!'我是默认值'}    即,有值时显示正常值,无值时显示默认值

    //在后台文件中定义变量
    String strVar = "世界你好";
    String str = null;
    //在页面中获取变量:
    <font color="red"> ${strVar!"我是空"} </font><br> //String获取
    <font color="red"> ${str!} </font><br>//str获取
    <font color="red"> ${str!"默认"} </font><br>//str获取
    //展示结果:String获取:世界你好  str获取:  str获取:默认

     ${封装对象.属性}   适用类型:对封装对象进行取值,例:${User.name}

    //在后台文件中封装对象User[ name,  age ]
    String name = "姓名";
    int age = 18;
    //在页面中获取变量:
    <font color="red"> ${User.name} </font><br>//name获取
    <font color="red"> ${User.age} </font><br>//age获取
    //展示结果:name获取:姓名    age获取:18

    ${date?String('yyyy-MM-dd')}  适用类型:对日期格式进行取值,要强调的是,定义Date类型的变量时,java.util.Date无法输出日期,须使用java.sql.Date

    //在后台文件中定义变量
    java.sql.Date date = new Date().getTime();
    java.sql.Date time = new Date().getTime();
    java.sql.Date datetime = new Date().getTime();
    //在页面中获取变量:
    <font color="red"> ${date?string('yyyy-MM-dd')} </font><br>//date获取
    <font color="red"> ${date?string('HH:mm:ss')} </font><br>//time获取
    <font color="red"> ${date?string('yyyy-MM-dd HH:mm:ss')} </font><br>//datetime获取
    //展示结果:未给出

    ${var?html}  适用类型:转义HTML内容

    //在后台文件中封装变量Menu[ name, model ]
    Menu m = new Menu(); 
    m.setName(" freemarker ");
    m.setModel("<font color = 'red'>我只是个菜单</font>");
    //在页面中获取变量:
    <font color="red"> ${m.model} </font><br>//非转义获取:
    ${m.model?html} </font><br>//转义获取:
    //展示结果:
    //非转义获取:我只是个菜单
    //转义获取:<font color = 'red'>我只是个菜单</font>

    <#assign num = 100 />  适用类型:定义变量,支持计算和赋值

    //在页面中定义变量:
    <#assign num = 100 />
    //在页面中获取变量
    <font color="red"> ${num)} </font><br>// num获取:
    <font color="red"> ${num * 10} </font><br>//计算结果:
    //展示结果:num获取:100    计算结果:1000

    对List集合进行取值
      <#list  list集合  as  item> 
        ${item}    --取值
      </#list>

    //在后台文件中定义变量
    List<String> strList = new ArrayList<String>();
    strList.add("第一个值");
    strList.add("第二个值");
    strList.add("第三个值");
    //在页面中获取变量:
    <#list  strList  as  item> 
      ${item!}<br/>    //取值
    </#list>
    //展示结果:
    //第一个值
    //第二个值
    //第三个值   

    对Map集合进行取值
      <#list map?keys as key>
        ${key}:${map[key]}
      </#list>

    //在后台文件中定义变量
    Map<String, Object> m = new HashMap<String, Object>();
    m.put("name","姓名");
    m.put("age",18);
    m.put("sex","男");
    //在页面中获取变量:
    <#list m?keys as key>
        ${key}:${m[key]}
    </#list>
    // 展示结果:
    //name:姓名
    //age:18
    //sex:男

      条件判断指令:                                

     <#if 条件>输出</#if>

    //在页面中定义变量并判断条件:
    <#assign age = 18 /><br>
    <#if age == 18>
        <font color="red"> age = 18</font>
    </#if>
    //展示结果: age = 18

    <#if 条件>  输出 <#else> 输出 </#if>

    //在页面中定义变量并判断条件:
    <#assign age = 20 /><br>
    <#if age == 18>
      <font color="red"> age = 18</font>
    <#else>
      <font color="red"> age != 18</font>
    </#if>
    //展示结果: age != 18

    <#if 条件1> 输出 <#elseif 条件2> 输出 <#else> 输出 </#if>

     //在页面中定义变量并判断条件:
    <#assign age = 20 /><br>
    <#if age &gt; 18>
      <font color="red">青年</font>
    <#elseif age == 18>
      <font color="red"> 成年</font>
    <#else>
      <font color="red"> 少年</font>
    </#if>
    //展示结果:成年

    switch  --常与case break default一起使用  参数可为字符串

    //在页面中定义变量并判断:
    <#switch var="星期一">
    <#case "星期一">
      油焖大虾
    <#break>
    <#case "星期二">
      炸酱面
    <#break>
    <#default>
      肯德基
    </#switch>
    //展示结果: 油焖大虾 

    自定义函数、自定义指令:               

    (1) 自定义函数 —— 实现TemplateMthodModelEx
    (2) 自定义指令 —— 实现TemplateDirectiveModel

    <@自定义指令名称 入参(key-value格式) ; 出参(list格式)>
      运行条件
    </@自定义指令名称>
    注意,不同的返回值用逗号( , )间隔开  
    <@mydirective parameters>...</@mydirective>//对于用户自定义的指令,如果指令没有嵌套内容,那么必须这么使用 
    <@mydirective parameters />

    常用内建函数、macro(宏指令)、function(函数指令):               

    (1) 常用内建函数
         

    处理字符串

    html

    对字符串进行HTML编码

    substring

    截取字符串,包头不包尾(下标)

    cap_first

     第一个字母大写 

    lower_case

    将字符串转成小写

    upper_case

    将字符串转成大写

    end_with     

    以什么字母结尾    

    contains              

    是否包含目标字符串

    date  datetime  time          

    转换成日期格式

    starts_with   

    以什么字母开头

    index_of             

    返回某个指定的字符串值在字符串中首次出现的位置(下标)

    last_index_of                  

    获取指定字符出现的最后位置(下标)

    split    

    分隔

    trim 

    去两端空格

    size

    获得集合中元素的个数

    int

    取得数字的整数部分

    处理数字

    string x?string("0.##")    

    变成小数点后几位

    round 

    四舍五入

    floor    

    去掉小数点

    ceiling 

    近1   变成整数

    处理list

    first

    取List值第一个值

    last

    取List值最后一个值

    seq_contains

    是否包含指定字符

    seq_index_of

     指定字符所在位置

    size

    集合大小

    reverse

    集合倒序排列

    sort

    对集合进行排序

    sort_by

    根据某一个属性排序

    chunk

     分块处理

    其他

    is_string:      

    是否为字符类型

    is_number:   

    是否为整数类型

    is_method:  

    是否为方法

    (): 

    判断整个变量

    has_content:     

    判断对象是否为空或不存在

    eval:

    求值

    (2) macro(宏指令)

         可以理解为java的封装方法,供其他地方使用。宏指令也称为自定义指令,macro指令

         调用:<@macro_name param />
         语法:<#macro  变量名  参数>  
                      <#nested/>  
                   </#macro>

         使用:<@变量名  />


    (3) function(函数指令)
         调用:${function_name(param)}
         语法:<#function  变量名  参数>  
                          <#return>  
                    </#function>

    FreeMarker 程序

    通过模拟简单的代码自动生产工具来感受第一个FreeMarker程序。

    项目目录结构:

    项目创建流程:

    第一步:创建一个maven项目导入 FreeMarker jar 包

    第二步:创建目录templates,并创建一个 FreeMarker模版文件 hello.ftl

    第三步:创建一个运行FreeMarker模版引擎的 FreeMarkerDemo.java 文件

    第四步:运行main方法后刷新项目

    pom.xml 文件 ,maven 项目核心文件,管理 jar 包。

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.freemark</groupId>
        <artifactId>freemarkerStudy</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <packaging>war</packaging>
    
        <dependencies>
            <dependency>
                <groupId>org.freemarker</groupId>
                <artifactId>freemarker</artifactId>
                <version>2.3.20</version>
            </dependency>
        </dependencies>
        
    </project>

     hello.ftl  FreeMarker基本语法: ${xxx} xxx 相当于占位符,java后台给xxx赋值后,再通过${}输出

    package ${classPath};
    public class ${className} {  
        public static void main(String[] args) {
            System.out.println("${helloWorld}");
        }
    }

    FreeMarkerDemo.java 核心方法,使用 FreeMarker 模版引擎。

    package com.freemark.hello;
    
    import java.io.BufferedWriter;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.OutputStreamWriter;
    import java.io.Writer;
    import java.util.HashMap;
    import java.util.Map;
    import freemarker.template.Configuration;
    import freemarker.template.Template;
    
    /**
     * 最常见的问题: 
     *     java.io.FileNotFoundException: xxx does not exist. 解决方法:要有耐心
     *     FreeMarker jar 最新的版本(2.3.23)提示 Configuration 方法被弃用
     * 代码自动生产基本原理:
     *     数据填充 freeMarker 占位符
     */
    public class FreemarkerDemo {
        
        private static final String TEMPLATE_PATH = "src/main/java/com/freemark/hello/templates";
        private static final String CLASS_PATH = "src/main/java/com/freemark/hello";
        
        public static void main(String[] args) {
            // step1 创建freeMarker配置实例
            Configuration configuration = new Configuration();
            Writer out = null;
            try {
                // step2 获取模版路径
                configuration.setDirectoryForTemplateLoading(new File(TEMPLATE_PATH));
                // step3 创建数据模型
                Map<String, Object> dataMap = new HashMap<String, Object>();
                dataMap.put("classPath", "com.freemark.hello");
                dataMap.put("className", "AutoCodeDemo");
                dataMap.put("helloWorld", "通过简单的 <代码自动生产程序> 演示 FreeMarker的HelloWorld!");
                // step4 加载模版文件
                Template template = configuration.getTemplate("hello.ftl");
                // step5 生成数据
                File docFile = new File(CLASS_PATH + "\" + "AutoCodeDemo.java");
                out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(docFile)));
                // step6 输出文件
                template.process(dataMap, out);
                System.out.println("^^^^^^^^^^^^^^^^^^^^^^^^AutoCodeDemo.java 文件创建成功 !");
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (null != out) {
                        out.flush();
                    }
                } catch (Exception e2) {
                    e2.printStackTrace();
                }
            }
        }
    }

     运行程序后刷新项目,会发现多了java类,xml。通过FreeMarker做了一个简易的工具类,公司的一个标准管理页面及其增删改查等功能,以及相关的配置文件(十三个文件),一个回车就全部自动生成(偷懒ing)。

    FreeMarker Web

    这里是和SpringMVC整合的,SpringMVC的配置就不多说了,源码地址:https://gitee.com/itdragon/springmvc

    //导入相关的jar   pom.xml
    <dependency>
      <groupId>org.freemarker</groupId>
      <artifactId>freemarker</artifactId>
      <version>2.3.20</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context-support</artifactId>
      <version>4.1.4.RELEASE</version>
    </dependency>
    
    //springmvc的配置文件
    <!-- 整合Freemarker -->
        <!-- 放在InternalResourceViewResolver的前面,优先找freemarker -->  
        <bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">  
            <property name="templateLoaderPath" value="/WEB-INF/views/templates"/>  
        </bean>  
        <bean id="viewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">  
            <property name="prefix" value=""/>  
            <property name="suffix" value=".ftl"/>  
            <property name="contentType" value="text/html; charset=UTF-8"/>
        </bean>
    
    //Controller 层
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    @Controller
    public class HelloFreeMarkerController {   
        @RequestMapping("/helloFreeMarker")
        public String helloFreeMarker(Model model) {
            model.addAttribute("name","ITDragon博客");  
            return "helloFreeMarker";
        }
    }
    
    //Freemarker文件
    <html>  
    <head>  
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
    <title>FreeMarker Web</title>  
    </head>  
    <body>  
        <h1>Hello ${name} !</h1>  
    </body>  
    </html>

    小结

    1. 知道了FreeMarker是一块模版引擎,可以生产xml,html,java等文件

    2. 知道了FreeMarker文件提供占位符,java文件提供数据,通过FreeMarker模版引擎生产有数据的页面,文中将数据放在Map中。web应用可以用setter/getter 方法

    3. 知道了FreeMarker语法中字符串的显示特殊字符,截取的操作。以及一些内置方法的使用

    4. 重点了解FreeMarker的空判断知识点。判断变量是否为空用 "??" ,如果变量为空设置默认值。如果不注意空问题,可能会出现黄色页面的提示哦!

    5. FreeMarker的宏概念,命名空间,引入文件,给变量赋值,集合的遍历等。

    6. Freemarker 整合SpringMVC。

  • 相关阅读:
    XML中<beans>中属性概述
    (转)深入理解Java:注解(Annotation)自定义注解入门
    maven 配置参数详解!
    maven setting.xml文件配置详情
    hashMap与 hashTable , ArrayList与linkedList 的区别(详细)
    jdbc参数
    linux下ftp命令的安装与使用
    java中的Iterator与增强for循环的效率比较
    命令行窗口常用的一些小技巧
    在eclispe的类中快速打出main方法
  • 原文地址:https://www.cnblogs.com/whatarewords/p/10937266.html
Copyright © 2011-2022 走看看