FreeMarker 快速入门

FreeMarker 快速入门

FreeMarker 快速入门

FreeMarker是一个很值得去学习的模版引擎。它是基于模板文件生成其他文本的通用工具。本章内容通过如何使用FreeMarker生成Html web 页面 和 代码自动生成工具来快速了解FreeMarker。

1 简介

FreeMarker是一款用java语言编写的模版引擎,它虽然不是web应用框架,但它很合适作为web应用框架的一个组件。

特点:

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

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

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

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

2 FreeMarker 程序

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

项目目录结构

项目创建流程

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

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

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

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

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

1

2 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

3 4.0.0

4 com.freemark

5 freemarkerStudy

6 0.0.1-SNAPSHOT

7 war

8

9

10

11 org.freemarker

12 freemarker

13 2.3.20

14

15

16

17

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

1 package ${classPath};

2

3 public class ${className} {

4

5 public static void main(String[] args) {

6 System.out.println("${helloWorld}");

7 }

8

9 }

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

1 package com.freemark.hello;

2

3 import java.io.BufferedWriter;

4 import java.io.File;

5 import java.io.FileOutputStream;

6 import java.io.OutputStreamWriter;

7 import java.io.Writer;

8 import java.util.HashMap;

9 import java.util.Map;

10

11 import freemarker.template.Configuration;

12 import freemarker.template.Template;

13

14 /**

15 * 最常见的问题:

16 * java.io.FileNotFoundException: xxx does not exist. 解决方法:要有耐心

17 * FreeMarker jar 最新的版本(2.3.23)提示 Configuration 方法被弃用

18 * 代码自动生产基本原理:

19 * 数据填充 freeMarker 占位符

20 */

21 public class FreemarkerDemo {

22

23 private static final String TEMPLATE_PATH = "src/main/java/com/freemark/hello/templates";

24 private static final String CLASS_PATH = "src/main/java/com/freemark/hello";

25

26 public static void main(String[] args) {

27 // step1 创建freeMarker配置实例

28 Configuration configuration = new Configuration();

29 Writer out = null;

30 try {

31 // step2 获取模版路径

32 configuration.setDirectoryForTemplateLoading(new File(TEMPLATE_PATH));

33 // step3 创建数据模型

34 Map dataMap = new HashMap();

35 dataMap.put("classPath", "com.freemark.hello");

36 dataMap.put("className", "AutoCodeDemo");

37 dataMap.put("helloWorld", "通过简单的 <代码自动生产程序> 演示 FreeMarker的HelloWorld!");

38 // step4 加载模版文件

39 Template template = configuration.getTemplate("hello.ftl");

40 // step5 生成数据

41 File docFile = new File(CLASS_PATH + "\\" + "AutoCodeDemo.java");

42 out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(docFile)));

43 // step6 输出文件

44 template.process(dataMap, out);

45 System.out.println("^^^^^^^^^^^^^^^^^^^^^^^^AutoCodeDemo.java 文件创建成功 !");

46 } catch (Exception e) {

47 e.printStackTrace();

48 } finally {

49 try {

50 if (null != out) {

51 out.flush();

52 }

53 } catch (Exception e2) {

54 e2.printStackTrace();

55 }

56 }

57 }

58

59 }

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

3 FreeMarker 语法

语法和java很类似,其中宏的概念可能比较陌生,先上代码

stringFreeMarker.ftl FreeMarker主要核心知识点

字符串输出:

${"Hello ${name} !"} / ${"Hello " + name + " !"}

<#assign cname=r"特殊字符完成输出(http:\www.baidu.com)">

${cname}

字符串截取 :

通过下标直接获取下标对应的字母: ${name[2]}

起点下标..结尾下标截取字符串:${name[0..5]}

算数运算:

<#-- 支持"+"、"-"、"*"、"/"、"%"运算符 -->

<#assign number1 = 10>

<#assign number2 = 5>

"+" : ${number1 + number2}

"-" : ${number1 - number2}

"*" : ${number1 * number2}

"/" : ${number1 / number2}

"%" : ${number1 % number2}

比较运算符:

<#if number1 + number2 gte 12 || number1 - number2 lt 6>

"*" : ${number1 * number2}

<#else>

"/" : ${number1 / number2}

内建函数:

<#assign data = "abcd1234">

第一个字母大写:${data?cap_first}

所有字母小写:${data?lower_case}

所有字母大写:${data?upper_case}

<#assign floatData = 12.34>

数值取整数:${floatData?int}

获取集合的长度:${users?size}

时间格式化:${dateTime?string("yyyy-MM-dd")}

空判断和对象集合:

<#if users??>

<#list users as user >

${user.id} - ${user.name}

<#else>

${user!"变量为空则给一个默认值"}

Map集合:

<#assign mapData={"name":"程序员", "salary":15000}>

直接通过Key获取 Value值:${mapData["name"]}

通过Key遍历Map:

<#list mapData?keys as key>

Key: ${key} - Value: ${mapData[key]}

通过Value遍历Map:

<#list mapData?values as value>

Value: ${value}

List集合:

<#assign listData=["ITDragon", "blog", "is", "cool"]>

<#list listData as value>${value}

include指令:

引入其他文件:<#include "otherFreeMarker.ftl" />

macro宏指令:

<#macro mo>

定义无参数的宏macro--${name}

使用宏macro: <@mo />

<#macro moArgs a b c>

定义带参数的宏macro-- ${a+b+c}

使用带参数的宏macro: <@moArgs a=1 b=2 c=3 />

命名空间:

<#import "otherFreeMarker.ftl" as otherFtl>

${otherFtl.otherName}

<@otherFtl.addMethod a=10 b=20 />

<#assign otherName="修改otherFreeMarker.ftl中的otherName变量值"/>

${otherFtl.otherName}

<#assign otherName="修改otherFreeMarker.ftl中的otherName变量值" in otherFtl />

${otherFtl.otherName}

otherFreeMarker.ftl 为了测试命名空间 和 include 指令的FreeMarker文件

其他FreeMarker文件

<#macro addMethod a b >

result : ${a + b}

<#assign otherName="另外一个FreeMarker的变量">

FreeMarkerDemo.java 核心方法

1 package com.freemark.demo;

2

3 import java.util.List;

4 import java.io.BufferedWriter;

5 import java.io.File;

6 import java.io.FileOutputStream;

7 import java.io.OutputStreamWriter;

8 import java.io.Writer;

9 import java.util.Date;

10 import java.util.ArrayList;

11 import java.util.HashMap;

12 import java.util.Map;

13

14 import freemarker.template.Configuration;

15 import freemarker.template.Template;

16

17 public class FreeMarkerDemo {

18

19 private static final String TEMPLATE_PATH = "src/main/java/com/freemark/demo/templates";

20

21 public static void main(String[] args) {

22 // step1 创建freeMarker配置实例

23 Configuration configuration = new Configuration();

24 Writer out = null;

25 try {

26 // step2 获取模版路径

27 configuration.setDirectoryForTemplateLoading(new File(TEMPLATE_PATH));

28 // step3 创建数据模型

29 Map dataMap = new HashMap();

30 dataMap.put("name", "itdragon博客");

31 dataMap.put("dateTime", new Date());

32

33 List users = new ArrayList();

34 users.add(new User(1, "ITDragon 博客"));

35 users.add(new User(2, "欢迎"));

36 users.add(new User(3, "You!"));

37 dataMap.put("users", users);

38 // step4 加载模版文件

39 Template template = configuration.getTemplate("stringFreeMarker.ftl");

40 // step5 生成数据

41 out = new OutputStreamWriter(System.out);

42 // step6 输出文件

43 template.process(dataMap, out);

44 } catch (Exception e) {

45 e.printStackTrace();

46 } finally {

47 try {

48 if (null != out) {

49 out.flush();

50 }

51 } catch (Exception e2) {

52 e2.printStackTrace();

53 }

54 }

55 }

56

57 }

User.java 为了测试 FreeMarker的集合对象

1 package com.freemark.demo;

2

3 public class User {

4

5 private Integer id;

6 private String name;

7

8 public User() {

9 }

10

11 public User(Integer id, String name) {

12 this.id = id;

13 this.name = name;

14 }

15

16 public Integer getId() {

17 return id;

18 }

19

20 public void setId(Integer id) {

21 this.id = id;

22 }

23

24 public String getName() {

25 return name;

26 }

27

28 public void setName(String name) {

29 this.name = name;

30 }

31

32 @Override

33 public String toString() {

34 return "User [id=" + id + ", name=" + name + "]";

35 }

36

37 }

最后的打印结果

字符串输出:

Hello itdragon博客 ! / Hello itdragon博客 !

特殊字符完成输出(http:\www.baidu.com)

字符串截取 :

通过下标直接获取下标对应的字母: d

起点下标..结尾下标截取字符串:itdrag

算数运算:

"+" : 15

"-" : 5

"*" : 50

"/" : 2

"%" : 0

比较运算符:

"*" : 50

内建函数:

第一个字母大写:Abcd1234

所有字母小写:abcd1234

所有字母大写:ABCD1234

数值取整数:12

获取集合的长度:3

时间格式化:2017-10-29

空判断和对象集合:

1 - ITDragon 博客

2 - 欢迎

3 - You!

Map集合:

直接通过Key获取 Value值:程序员

通过Key遍历Map:

Key: name - Value: 程序员

Key: salary - Value: 15,000

通过Value遍历Map:

Value: 程序员

Value: 15,000

List集合:

ITDragon blog is cool

include指令:

其他FreeMarker文件

macro宏指令:

使用宏macro: 定义无参数的宏macro--itdragon博客

使用带参数的宏macro: 定义带参数的宏macro-- 6

命名空间:

另外一个FreeMarker的变量

result : 30

另外一个FreeMarker的变量

修改otherFreeMarker.ftl中的otherName变量值

语法详解

数据类型

和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 配合使用

内建函数

FreeMarker 提供了一些内建函数来转换输出,其结构:变量?内建函数,这样就可以通过内建函数来转换输出变量。

1. html: 对字符串进行HTML编码;2. cap_first: 使字符串第一个字母大写;3. lower_case: 将字符串转成小写;4. upper_case: 将字符串转成大写;5. size: 获得集合中元素的个数;6. int: 取得数字的整数部分。

变量空判断

! 指定缺失变量的默认值;一般配置变量输出使用?? 判断变量是否存在。一般配合if使用 <#if value??>

宏指令

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

语法很简单:<#macro val > 声明macro ; 使用macro <@val />

命名空间

可以理解为java的import语句,为避免变量重复。一个重要的规则就是:路径不应该包含大写字母,使用下划线_分隔词语,myName --> my_name

语法很简单:<#import "xxx.ftl" as val>

其他没有说明的语法是因为和java一样,没什么特别之处。所以没有列出来。

4 FreeMarker Web

这里是和SpringMVC整合的,SpringMVC的配置就不多说了,笔者也写过相关的文章,同时也会提供源码

导入相关的jar pom.xml

org.freemarker

freemarker

2.3.20

org.springframework

spring-context-support

4.1.4.RELEASE

springmvc的配置文件:

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文件

FreeMarker Web

Hello ${name} !

源码地址:https://gitee.com/itdragon/springmvc

5 小结

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

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

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

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

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

6. Freemarker 整合SpringMVC。

到这里FreeMarker的入门就结束了,是不是很简单。如果有什么不对的地方,请指正!

扩展链接:Sort 坑爹的字符串排序

相关推荐

世界杯各分组的比赛(世界杯分组规则)世界杯足球赛分组规则:如何比赛
英雄联盟手游S17赛季开始时间一览
best365官网手机版

英雄联盟手游S17赛季开始时间一览

📅 07-25 👁️ 8210
2024全国一本大学录取分数线一览表(各学校最低投档线)
七鬼五二三游戏规则(七鬼五二三游戏规则最大的)
best365官网手机版

七鬼五二三游戏规则(七鬼五二三游戏规则最大的)

📅 08-04 👁️ 4103
2018年国际足联世界杯预选赛 (亚洲区)
best365官网手机版

2018年国际足联世界杯预选赛 (亚洲区)

📅 06-30 👁️ 2293
电话资源渠道有哪些 (怎么获取电话号码资源)
bet体育365官网怎么样

电话资源渠道有哪些 (怎么获取电话号码资源)

📅 08-22 👁️ 2334