https://www.cnblogs.com/itdragon/p/7750903.htmlhtml
FreeMarker是一个很值得去学习的模版引擎。它是基于模板文件生成其余文本的通用工具。本章内容经过如何使用FreeMarker生成Html web 页面 和 代码自动生成工具来快速了解FreeMarker。java
FreeMarker是一款用java语言编写的模版引擎,它虽然不是web应用框架,但它很合适做为web应用框架的一个组件。git
特色:程序员
1. 轻量级模版引擎,不须要Servlet环境就能够很轻松的嵌入到应用程序中web
2. 能生成各类文本,如html,xml,java,等spring
3. 入门简单,它是用java编写的,不少语法和java类似apache
工做原理:(借用网上的图片)mvc
这里经过模拟简单的代码自动生产工具来感觉第一个FreeMarker程序。app
项目目录结构框架
项目建立流程
第一步:建立一个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 <modelVersion>4.0.0</modelVersion> 4 <groupId>com.freemark</groupId> 5 <artifactId>freemarkerStudy</artifactId> 6 <version>0.0.1-SNAPSHOT</version> 7 <packaging>war</packaging> 8 9 <dependencies> 10 <dependency> 11 <groupId>org.freemarker</groupId> 12 <artifactId>freemarker</artifactId> 13 <version>2.3.20</version> 14 </dependency> 15 </dependencies> 16 17 </project>
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<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)。
语法和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} </#if> 内建函数: <#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} </#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<User> users = new ArrayList<User>(); 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??></#if>
能够理解为java的封装方法,供其余地方使用。宏指令也称为自定义指令,macro指令
语法很简单:<#macro val > 声明macro </#macro>; 使用macro <@val />
命名空间
能够理解为java的import语句,为避免变量重复。一个重要的规则就是:路径不该该包含大写字母,使用下划线_分隔词语,myName --> my_name
语法很简单:<#import "xxx.ftl" as val>
其余没有说明的语法是由于和java同样,没什么特别之处。因此没有列出来。
这里是和SpringMVC整合的,SpringMVC的配置就很少说了,笔者也写过相关的文章,同时也会提供源码
导入相关的jar pom.xml
<!-- freeMarker start --> <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> </dependencies> <!-- freeMarker end -->
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>
源码地址:https://gitee.com/itdragon/springmvc
1. 知道了FreeMarker是一块模版引擎,能够生产xml,html,java等文件
2. 知道了FreeMarker文件提供占位符,java文件提供数据,经过FreeMarker模版引擎生产有数据的页面,文中是将数据放在Map中。web应用能够用setter/getter 方法
3. 知道了FreeMarker语法中字符串的显示特殊字符,截取的操做。以及一些内置方法的使用
4. 重点了解FreeMarker的空判断知识点。判断变量是否为空用 "??" ,若是变量为空设置默认值。若是不注意空问题,可能会出现黄色页面的提示哦!
5. FreeMarker的宏概念,命名空间,引入文件,给变量赋值,集合的遍历等。
6. Freemarker 整合SpringMVC。
到这里FreeMarker的入门就结束了,是否是很简单。若是有什么不对的地方,请指正!