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 <project xmlns=“http://maven.apache.org/POM/4.0.0” xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance
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基本语法: x x x x x x 相 当 于 占 位 符 , j a v a 后 台 给 x x x 赋 值 后 , 再 通 过 {xxx} xxx 相当于占位符,java后台给xxx赋值后,再通过 xxxxxxjavaxxx{}输出

复制代码
1 package ${classPath};
2
3 public class KaTeX parse error: Expected '}', got 'EOF' at end of input: …m.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<String, Object> dataMap = new HashMap<String, Object>();
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}

字符串截取 :
通过下标直接获取下标对应的字母: n a m e [ 2 ] 起 点 下 标 . . 结 尾 下 标 截 取 字 符 串 : {name[2]} 起点下标..结尾下标截取字符串: 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}
</#if>

内建函数:
<#assign data = “abcd1234”>
第一个字母大写: d a t a ? c a p f i r s t 所 有 字 母 小 写 : {data?cap_first} 所有字母小写: data?capfirst{data?lower_case}
所有字母大写:KaTeX parse error: Expected 'EOF', got '#' at position 20: …a?upper_case} <#̲assign floatDat…{floatData?int}
获取集合的长度: u s e r s ? s i z e 时 间 格 式 化 : {users?size} 时间格式化: users?size{dateTime?string(“yyyy-MM-dd”)}

空判断和对象集合:
<#if users??>
<#list users as user >
${user.id} - ${user.name}
</#list>
<#else>
${user!“变量为空则给一个默认值”}
</#if>

Map集合:
<#assign mapData={“name”:“程序员”, “salary”:15000}>
直接通过Key获取 Value值:${mapData[“name”]}
通过Key遍历Map:
<#list mapData?keys as key>
Key: ${key} - Value: ${mapData[key]}
</#list>
通过Value遍历Map:
<#list mapData?values as value>
Value: ${value}
</#list>

List集合:
<#assign listData=[“ITDragon”, “blog”, “is”, “cool”]>
<#list listData as value>${value} </#list>

include指令:
引入其他文件:<#include “otherFreeMarker.ftl” />

macro宏指令:
<#macro mo>
定义无参数的宏macro–${name}
</#macro>
使用宏macro: <@mo />
<#macro moArgs a b c>
定义带参数的宏macro-- ${a+b+c}
</#macro>
使用带参数的宏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}
</#macro>
<#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<String, Object> dataMap = new HashMap<String, Object>();
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 , KaTeX parse error: Expected 'EOF', got '}' at position 8: {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??></#if>

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

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

命名空间

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

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

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

4 FreeMarker Web
这里是和SpringMVC整合的,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的配置文件:

复制代码

<!-- 放在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文件

复制代码

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的入门就结束了,是不是很简单。如果有什么不对的地方,请指正!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值