zoukankan      html  css  js  c++  java
  • 【学习笔记】初识FreeMarker简单使用

    楔子:

       之前在和同事讨论,同事说“jsp技术太古老了,有几种页面技术代替,比如FreeMarker、Velocity、thymeleaf,jsp快废弃了……”云云。我这一听有点心虚……我在后端部分越刨越深,页面装配技术什么的好像只知道有jsp……趁放假自己补补课啦~

    简介:

      FreeMarker是一个模板引擎,一个基于模板生成文本输出的通用工具,纯Java编写。类似jsp,简单来讲就是模板加数据模型,然后输出页面。

    图片来自尚学堂课件,侵权删

    图片来自尚学堂课件,侵权删

      相对于jsp,FreeMarker的性能略差几十毫秒,但是复杂页面上性能比jsp更佳。

      而且最好的一点,我感觉应该是可以直接把美工写好的html放进模板中使用(无需加jsp头等),FreeMarker自带的一些标签用着也很简单。FreeMarker的模板文件格式为ftl,也可以直接用html

      FreeMarker可以应用更多的场景,与容器无关;而jsp要求有JVM环境,只能应用于web应用中。

    HelloWorld:

      第一个FreeMarker代码

    新建一个Java project,起名为 FreeMarker,在src外部新建一个文件夹命名为templates,如图:

    在templates中新建一个file,命名为first.ftl,添加如下代码(其中的表达式类似于EL表达式):

    hello,${user},这是你的第一个FreeMarker程序!

    下载FreeMarker.jar并引入项目

    新建FirstFreeMarker类,代码如下:

     1 package com.hellxz;
     2 
     3 import java.io.File;
     4 import java.io.IOException;
     5 import java.io.OutputStreamWriter;
     6 import java.io.Writer;
     7 import java.util.HashMap;
     8 import java.util.Map;
     9 
    10 import freemarker.template.Configuration;
    11 import freemarker.template.Template;
    12 import freemarker.template.TemplateException;
    13 
    14 /**
    15  * 第一个FreeMarker程序
    16  * 
    17  * @author hellxz
    18  */
    19 public class FirstFreeMarker {
    20 
    21     @SuppressWarnings({"rawtypes","unchecked"})
    22     public static void main(String[] args) throws IOException, TemplateException {
    23         // 创建Freemarker配置实例
    24         Configuration cfg = new Configuration();
    25         cfg.setDirectoryForTemplateLoading(new File("templates"));
    26 
    27         // 创建数据模型
    28         Map root = new HashMap();
    29         root.put("user", "老张");
    30 
    31         // 加载模板文件
    32         Template t1 = cfg.getTemplate("first.ftl");
    33 
    34         // 显示生成的数据,将合并后的数据打印到控制台
    35         Writer out = new OutputStreamWriter(System.out);
    36         t1.process(root, out);
    37         out.flush();
    38         out.close();
    39 
    40     }
    41 
    42 }

    运行代码,查看输出:

    hello,老张,这是你的第一个FreeMarker程序!

    测试举例:

    本例子基本涵盖了大部分FreeMarker特有的属性,参考Java语言不同点写就,相同点并没有测试。通过观察代码可以很清晰的看出这些函数、指令的使用方法

    新建一个Address类:

     1 package com.hellxz;
     2 
     3 /**
     4  * 地址
     5  * 
     6  * @author hellxz
     7  */
     8 public class Address {
     9 
    10     private String country; // 国家
    11     private String city; // 城市
    12 
    13     //getters & setters
    14     public String getCountry() {
    15         return country;
    16     }
    17 
    18     public void setCountry(String country) {
    19         this.country = country;
    20     }
    21 
    22     public String getCity() {
    23         return city;
    24     }
    25 
    26     public void setCity(String city) {
    27         this.city = city;
    28     }
    29 
    30     public Address(String country, String city) {
    31         this.country = country;
    32         this.city = city;
    33     }
    34 }

    新建一个TestFreeMarker类,代码如下:

     1 package com.hellxz;
     2 
     3 import java.io.File;
     4 import java.io.IOException;
     5 import java.io.OutputStreamWriter;
     6 import java.io.Writer;
     7 import java.util.ArrayList;
     8 import java.util.HashMap;
     9 import java.util.Map;
    10 import java.util.Random;
    11 
    12 import freemarker.template.Configuration;
    13 import freemarker.template.Template;
    14 import freemarker.template.TemplateException;
    15 
    16 /**
    17  * FreeMarker Test
    18  * 
    19  * @author hellxz
    20  */
    21 public class TestFreeMarker {
    22 
    23     @SuppressWarnings({ "rawtypes", "unchecked" })
    24     public static void main(String[] args) throws IOException, TemplateException {
    25         //1.创建配置文件
    26         Configuration conf = new Configuration();
    27         //2.设置模板目录
    28         conf.setDirectoryForTemplateLoading(new File("templates"));
    29         //3.数据模型
    30         Map<String,Object> map = new HashMap<>();
    31         map.put("user", "老张");
    32         map.put("random",new Random().nextInt(100));
    33         //新建一个list放入map中,用于测试遍历list操作
    34         ArrayList list = new ArrayList();
    35         list.add(new Address("中国","上海"));
    36         list.add(new Address("日本","东京"));
    37         map.put("list", list);
    38         //测试内建函数
    39         map.put("html5", "<b>大写的文字</b>");
    40         map.put("name", "hellxz");
    41         map.put("upper", "ABCDEF");
    42         //4.获取模板文件
    43         Template template = conf.getTemplate("a.ftl");
    44         //5.输出流
    45         Writer out = new OutputStreamWriter(System.out);
    46         //6.生成文件流输出
    47         template.process(map, out);
    48         out.flush();
    49         out.close();
    50     }
    51 }

    在templates文件夹下新建a.ftl

      1 hello,${user},今天看起来很精神嘛!
      2 ----------------------------------
      3 if分支语句测试:
      4 <#if user=="老张">
      5         老张!
      6 </#if>
      7 ----------------------------------
      8 if else 分支测试:
      9 <#if user=="老李">
     10         老李
     11 <#else>
     12         老张
     13 </#if>
     14 ----------------------------------
     15 if else if else 测试:
     16 因为大于小于号等会被转义,使用简写代替比较符号
     17 gt(great than的简写) 代替 >
     18 lt(less than的简写) 代替 <
     19 gte(great than equal的简写) 代替 >=
     20 lte (less than equal的简写) 代替 <=
     21 <#if random gt 80>
     22         优秀
     23 <#elseif random gt 60>
     24         及格
     25 <#else>
     26         不及格
     27 </#if>
     28 ----------------------------------
     29 遍历list测试:
     30 <#list list as addr>
     31         ${addr.country} ${addr.city}
     32 </#list>
     33 ----------------------------------
     34 include包含测试:
     35 <#include "include.txt"/>
     36 ----------------------------------
     37 macro无参函数(宏函数)测试:
     38 定义函数:
     39 <#macro m1>
     40     我是函数内容
     41 </#macro>
     42 调用函数测试:
     43 <@m1/><@m1/><#--这是注释内容:这里调用了两次函数-->
     44 ----------------------------------
     45 macro带参函数<#--(格式为"<#macro 函数名 [变量1 变量2 变量3 ……] </#macro>")-->:
     46 <#macro cc a b c>
     47     ${a}/${b}/${c}
     48 </#macro>
     49 调用测试<#--(格式为:"<@函数名 [变量1值 变量2值 变量3值 ……] </#macro>")-->:
     50 <@cc "中" "明" "月"/>
     51 ----------------------------------
     52 nested测试:
     53 用于一大段代码的嵌入
     54 <#macro border>
     55     <html>
     56         <head>
     57             <body>
     58                 <#nested/>
     59             </body>
     60         </head>
     61     </html>
     62 </#macro>
     63 向nested部分添加内容:
     64 <@border>
     65                 <h1>我是nested的内容</h1>
     66 </@border>
     67 ----------------------------------
     68 测试命名空间:
     69 <#import "b.ftl" as bb  />
     70 <@bb.copyright date="2010-2011" />
     71 ${bb.mail}
     72 <#assign mail="my@163.com"  />
     73 ${mail}
     74 <#assign mail="my@163.com" in bb  />
     75 ${bb.mail}
     76 -----------------------------------
     77 声明、指定变量assign:
     78 测试数据类型:
     79 <#assign ss="hellxz"/>
     80 文本型:${ss}
     81 <#assign s1=1 />
     82 数值型:${s1}
     83 <#assign s2=true/>
     84 布尔型:<#if s2>布尔型</#if>
     85 -------------------------------------
     86 字符串常见内建函数:
     87 html转义:${html5?html}
     88 cap_first(首字母大写):${name?cap_first}
     89 upper_case(转大写):${name?upper_case}
     90 lower_case(转小写):${upper?lower_case}
     91 数值常见内建函数:
     92 int(取整数部分)
     93 集合内建函数:
     94 size(取集合大小)
     95 ------------------------------------
     96 字符串空值处理:
     97 FreeMarker不支持空值,如果为空直接报错
     98 没有定义直接引用
     99 <#-- ${sss} 直接报错了-->
    100 空值处理:
    101 ${sss!}<#-- 为空则输出空字符串 -->
    102 ${sss!"default"} <#--设置默认值,为空自动使用-->
    103 ------------------------------------------
    104 ??布尔值处理
    105 <#if user??>
    106 如果该值存在,返回true,相当于 if user != null
    107 <#else>
    108 该值不存在返回false
    109 </#if>

    新建b.ftl 用于测试命名空间

    1 <#macro copyright date>
    2   <p>Copyright (C) ${date} 北京尚学堂.</p> 
    3 </#macro> 
    4 <#assign mail = "bjsxt@163.com">

    在templates下新建include.txt,用于测试include指令

    我是被包含的内容!

    运行TestFreeMarker,查看输出(这里为了方便比较,加上行号):

     1 hello,老张,今天看起来很精神嘛!
     2 ----------------------------------
     3 if分支语句测试:
     4         老张!
     5 ----------------------------------
     6 if else 分支测试:
     7         老张
     8 ----------------------------------
     9 if else if else 测试:
    10 因为大于小于号等会被转义,使用简写作为比较符号
    11 gt=great than = >
    12 lt=less than = <
    13 gte = great than equal = >=
    14 lte = less than equal = <=
    15         及格
    16 ----------------------------------
    17 遍历list测试:
    18         中国 上海
    19         日本 东京
    20 ----------------------------------
    21 include包含测试:
    22 我是被包含的内容!
    23 ----------------------------------
    24 macro无参函数(宏函数)测试:
    25 定义函数:
    26 调用函数测试:
    27     我是函数内容
    28     我是函数内容
    29 ----------------------------------
    30 macro带参函数:
    31 调用测试:
    32     中/明/33 ----------------------------------
    34 nested测试:
    35 用于一大段代码的嵌入
    36 向nested部分添加内容:
    37     <html>
    38         <head>
    39             <body>
    40                 <h1>我是nested的内容</h1>
    41             </body>
    42         </head>
    43     </html>
    44 ----------------------------------
    45 测试命名空间:
    46   <p>Copyright (C) 2010-2011 北京尚学堂.</p> 
    47 bjsxt@163.com
    48 my@163.com
    49 my@163.com
    50 -----------------------------------
    51 声明、指定变量assign:
    52 测试数据类型:
    53 文本型:hellxz
    54 数值型:1
    55 布尔型:布尔型
    56 -------------------------------------
    57 字符串常见内建函数:
    58 html转义:&lt;b&gt;大写的文字&lt;/b&gt;
    59 cap_first(首字母大写):Hellxz
    60 upper_case(转大写):HELLXZ
    61 lower_case(转小写):abcdef
    62 数值常见内建函数:
    63 int(取整数部分)
    64 集合内建函数:
    65 size(取集合大小)
    66 ------------------------------------
    67 字符串空值处理:
    68 FreeMarker不支持空值,如果为空直接报错
    69 没有定义直接引用
    70 空值处理:
    71 
    72 default 
    73 ------------------------------------------
    74 ??布尔值处理
    75 如果该值存在,返回true,相当于 if user != null

     看了一下漏了一个日期处理,这里补一下:

    map.put("date", new Date());

    a.ftl中模板写法:

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

    输出:

    2018-02-18 16:18:10

    字符串连接
    字符串连接有两种语法:
    1) 使用${..}#{..}在字符串常量内插入表达式的值;
    (2)  直接使用连接运算符“+”连接字符串。
    如,下面两种写法等效:
                  ${"Hello, ${user}"}                                                                                                               
                  ${"Hello, " + user + "!"}                                                                                                        
    有一点需要注意: ${..}只能用于文本部分作为插值输出,而不能用于比较等其他用途,如:
                  <#if ${isBig}>Wow!</#if>                                                                                                               
                  <#if "${isBig}">Wow!</#if>                                                                                                             
    应该写成:
                  <#if isBig>Wow!</#if>   

    截取子串
    截取子串可以根据字符串的索引来进行,如果指定一个索引值,则取得字符串该索引处的字符;如果指定两个索引值,则截取两个索引中间的字符串子串。如:
                  <#assign number="01234">
                  ${number[0]} <#-- 输出字符0 -->
                  ${number[0..3]} <#-- 输出子串“0123” -->

     

     本文为FreeMarker简单的语法使用,servlet以及struts部分见我的下篇博客

    http://www.cnblogs.com/hellxz/p/8453239.html

     

  • 相关阅读:
    MySQL优化器 limit影响的case
    Innodb物理存储结构系列1
    Innodb 锁系列1 同步机制
    javascript变量作用域 全局及局部
    测试20160422
    python-推荐
    python问题:IndentationError:expected an indented block错误解决
    协同过滤(推荐方法)——数据挖掘
    教你在Excel里做GA的水平百分比图的详细步骤(图文教程)-成为excel大师(1)
    win7搭建ios开发环境
  • 原文地址:https://www.cnblogs.com/hellxz/p/8452880.html
Copyright © 2011-2022 走看看