Freemarker入门

写在前面的话

从2016年开始工作到现在, 从来没有整理汇总过自己所学。 所以趁着现在在做新项目,打算把自己所接触到的技术点通过文档的形式记录下来。
一方面是巩固下之前所学,加深印象。另一方面也是为了形成自己的知识库, 方便以后查看。

那么就先从Freemarker开始

什么是Freemarker

Freemarker是一款模板生成引擎, 是一种基于模板生成静态文件的通用技术。比如生成静态html文件, 代码生成器中生成通用Java文件等等。现在也用来替代jsp进行数据展示

Freemarker是采用Java语言编写的

Freemarker 使用步骤

  1. 首先需要定义模板页面 freemarker文件后缀为.ftl
  2. 后台读取模板页面,已键值对的形式给Freemarker传递数据替换模板中的取值表达式
  3. 根据配置的路径生成静态文件

实例代码: 生成一个java文件

环境: maven生成的java项目



  org.freemarker
  freemarker
  2.3.23

  1. FreemarkerUtil 包含对Freemarker的配置和生成文件的工具

public class FreemarkerUtil {

    /**
     * 获取Freemarker的Template
     *
     * @param fileName 模板名称
     * @return
     * @throws IOException
     */
    public Template getTemplate(String fileName) throws IOException {
        Configuration cfg = new Configuration();

        // 定义模版的位置
        //从指定文件夹中获取
        //cfg.setDirectoryForTemplateLoading(new File(""));
        //从类路径中
        cfg.setClassForTemplateLoading(getClass(), "/templates");
        // 设置对象包装器
        cfg.setObjectWrapper(new DefaultObjectWrapper());
        // 设置异常处理器
        cfg.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);

        return cfg.getTemplate(fileName);
    }

    /**
     * 输出文件
     * @param fileName  模板名称
     * @param map       数据
     * @param path      生成后的文件路径
     */
    public void out(String fileName, Map map, String path) {
        PrintWriter printWriter = null;

        try {
            Template template = getTemplate(fileName);
            
            printWriter = new PrintWriter(new FileWriter(path));

            //生成文件
            template.process(map, printWriter);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (TemplateException e) {
            e.printStackTrace();
        } finally {
            if (printWriter != null) {
                printWriter.close();
            }
        }
    }
}
  1. 在resources中新建templates文件夹, 在其中配置App.ftl模板文件
<#-- 我是freemarker中的注释 -->
<#-- 生成文件 -->
public class App {
    public static void main(String[] args) {
        System.out.println("${name}");
    }
}

很简单的java输出文件

  1. Junit进行测试
public class App {

    FreemarkerUtil mFreemarkerUtil;

    @Before
    public void before() {
        mFreemarkerUtil = new FreemarkerUtil(); //初始化
    }

    @Test
    public void outFile() {
      //传递数据
      Map map = new HashMap() {{
        put("name", "hello world");
      }};

      //在D盘下生成App.java文件
      mFreemarkerUtil.out("App.ftl", map, "D:\\tmp\\App.java");
    }

}
  1. 展示:完美生成可执行的java文件。 就这样简单的小例子,先熟悉下Freemarker的用法
freemarker测试代码展示效果.png

Freemarker是通过键值对的方式传递数据, 所以在ftl中间中要展示后台传递的数据 只需要${key}的形式即可 类似于jsp的EL表达式

常用指令

list指令

对传递过来的集合数据进行迭代

语法

//普通数据
<#list lists as item> //lists:集合数据  item:循环变量 item_index: 循环索引
  ${item}


//循环map
<#list maps?keys as key>
  ${maps[key]}


//循环集合中的对象
<#list lists as item>
  ${item.字段}


//其他属性
${lists?size}   //获取集合的长度

if else 指令

主要是做if判断用的,要注意的是条件等式必须用括号括起来。

语法

<#if 条件>
  //一个判断
<#elseif 条件>
  //另外一种判断
<#else>
  //除以上之外的其他判断

注意点:

  1. elseif 和 else 必须包含在 if 中
  2. if 中不是必须出现elseif 和else 也可以单独if 判断,然后结束

小实例:结合list指令和if else指令 展示列表 并隔行换色

template1.ftl文件 (节省篇幅 只贴出有用代码)


  


    <#-- 我是freemarker中的注释 --> <#--循环--> <#list list as l> <#if (l_index + 1) % 2 == 0> <#--判断 循环索引于2的余数是否为0-->
  • <#elseif (l_index + 1) % 3 == 0> <#--判断 循环索引于3的余数是否为0-->
  • <#else>
  • ${l}- ${l_index + 1}

java代码

@Test
public void template1() {
    List list = new ArrayList();
    for (int i = 'A'; i <= 'z'; i++) {
        list.add((char) i + "");
    }

    mRoot.put("list", list);

    //对应上的例子的FreemarkerUtil
    mFreemarkerUtil.out("template1.ftl", mRoot, "D:\\tmp\\template1.html");
}

展示效果

list和if小例子展示效果.png

可以看到在html生成成功, 打开按照if 判断的形式循环展示 (-_- 完美)

include 指令

该指令表示导入其他的文件或者freemarker文件, 一般用于导入公共文件, 如网站的头部, 公共资源文件,版权信息等

语法

//这里的path代表文件的路径
<#include path>

import 指令

该指令类似于include, 不同的是import导入进来后, 可以在该文件中使用被导入文件的宏组件

语法

// path 文件路径  p 别名

<#import path as p>

小实例: include 和 import 展示其区别

include和import的区别展示效果.png

setting 指令

该指令用于动态设置freeMarker的运行环境。

语法

<#setting name=value>

name的取值范围包括:

  1. locale: 指定该模板所用的国家/语言选项
  2. number_format: 定格式化输出数字的格式
  3. boolean_format: 指定两个布尔值的语法格式,默认值是true,false
  4. date_format, time_format, datetime_format: 指定显示的时间格式
  5. time_zone:设置格式化输出日期时所使用的时区

插值

插值就是${...}或#{...}格式的部分,将使用数据模型中的部分替代输出

字符串插值

${name} //直接输出

数字值

通过setting配置数字显示格式

<#setting number_format="0.##">
${150}  -->>>   150.00  
${150.568}  -->>>   150.57  //四舍五入的形式

通过string指令

${150?string("0.##")}  -->>>   150.00  //同样的展示效果

日期展示, 同样可以使用两种形式来配置, 这里只展示通过string指令来展示的效果

${.now?string("yyyy-MM-dd HH:mm:ss")}  ->>  2019-07-16 15:57:40 //展示当前时间 

字符串为空或者为null判断

${prices!"111"} //如果prices没有定义或者为null 那么就显示111 否则就显示prices的值

关于更多的的指令的描述和学习, 可以 点击这里查看中文在线手册

SpringMVC + Freemarker整合使用

前面说到Freemarker不只是模板引擎, 还可以替代jsp当做界面展示效果, 那么我们来看下和SpringMVC的整合

maven 配置 Freemarker的jar包


  org.freemarker
  freemarker
  2.3.23



  org.springframework
  spring-context-support
  4.3.18.RELEASE

spring-mvc.xml




  
  
  
  
    org.springframework.web.servlet.view.freemarker.FreeMarkerView
  
  



  
    
      classpath:freemarker.properties
    
  



  
    /WEB-INF/ftl/
  
  

freemarker.properties

#设置标签类型:square_bracket:[]     auto_detect:[]<>
tag_syntax=auto_detect
#模版缓存时间,单位:秒
template_update_delay=0
default_encoding=UTF-8
output_encoding=UTF-8
locale=zh_CN
#设置数字格式 ,防止出现 000.00
number_format=\#
#变量为空时,不会报错
classic_compatible=true
date_format=yyyy-MM-dd 
time_format=HH\:mm\:ss 
datetime_format=yyyy-MM-dd HH\:mm\:ss

controller中使用

@RequestMapping("/center")
public String center(HttpServletRequest request, ModelMap map) {

    map.put("name", "Hello World");

    //完整路径: /WEB-INF/ftl/index.ftl
    return "/index";
}

到此 关于SpringMVC + Freemarker整合就已经完成。

该内容只是讲解关于Freemarker简单的内容, 更多相关内容参考

  1. Freemarker官方文档
  2. Freemarker中文在线手册

预告

通过本章节Freemarker算是简单入门, 那么下一节通过实战来加深对Freemarker的印象

实战演练, Freemarker + MyBatis 配合开发我们的代码生成器

你可能感兴趣的:(Freemarker入门)