写在前面的话
从2016年开始工作到现在, 从来没有整理汇总过自己所学。 所以趁着现在在做新项目,打算把自己所接触到的技术点通过文档的形式记录下来。 一方面是巩固下之前所学,加深印象。另一方面也是为了形成自己的知识库, 方便以后查看。
那么就先从Freemarker开始
什么是Freemarker
Freemarker是一款模板生成引擎, 是一种基于模板生成静态文件的通用技术。比如生成静态html文件, 代码生成器中生成通用Java文件等等。现在也用来替代jsp进行数据展示
Freemarker是采用Java语言编写的
Freemarker 使用步骤
- 首先需要定义模板页面 freemarker文件后缀为.ftl
- 后台读取模板页面,已键值对的形式给Freemarker传递数据替换模板中的取值表达式
- 根据配置的路径生成静态文件
实例代码: 生成一个java文件
环境: maven生成的java项目
<!--依赖-->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.23</version>
</dependency>
- 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<String, Object> 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();
}
}
}
}
- 在resources中新建templates文件夹, 在其中配置App.ftl模板文件
<#-- 我是freemarker中的注释 -->
<#-- 生成文件 -->
public class App {
public static void main(String[] args) {
System.out.println("${name}");
}
}
很简单的java输出文件
- Junit进行测试
public class App {
FreemarkerUtil mFreemarkerUtil;
@Before
public void before() {
mFreemarkerUtil = new FreemarkerUtil(); //初始化
}
@Test
public void outFile() {
//传递数据
Map<String, Object> map = new HashMap<String, Object>() {{
put("name", "hello world");
}};
//在D盘下生成App.java文件
mFreemarkerUtil.out("App.ftl", map, "D:\\tmp\\App.java");
}
}
- 展示:完美生成可执行的java文件。 就这样简单的小例子,先熟悉下Freemarker的用法
Freemarker是通过键值对的方式传递数据, 所以在ftl中间中要展示后台传递的数据 只需要${key}的形式即可 类似于jsp的EL表达式
常用指令
list指令
对传递过来的集合数据进行迭代
语法
//普通数据
<#list lists as item> //lists:集合数据 item:循环变量 item_index: 循环索引
${item}
</#list>
//循环map
<#list maps?keys as key>
${maps[key]}
</#list>
//循环集合中的对象
<#list lists as item>
${item.字段}
</#list>
//其他属性
${lists?size} //获取集合的长度
if else 指令
主要是做if判断用的,要注意的是条件等式必须用括号括起来。
语法
<#if 条件>
//一个判断
<#elseif 条件>
//另外一种判断
<#else>
//除以上之外的其他判断
</#if>
注意点:
- elseif 和 else 必须包含在 if 中
- if 中不是必须出现elseif 和else 也可以单独if 判断,然后结束
小实例:结合list指令和if else指令 展示列表 并隔行换色
template1.ftl文件 (节省篇幅 只贴出有用代码)
<head>
<style>
li { background: #FFF; color: #000; }
li.active { background: #F00; color: antiquewhite; }
li.primary { background: #FF0; color: aqua; }
</style>
</head>
<body>
<ul>
<#-- 我是freemarker中的注释 -->
<#--循环-->
<#list list as l>
<#if (l_index + 1) % 2 == 0> <#--判断 循环索引于2的余数是否为0-->
<li class="active">
<#elseif (l_index + 1) % 3 == 0> <#--判断 循环索引于3的余数是否为0-->
<li class="primary">
<#else>
<li>
</#if>
${l}- ${l_index + 1}
</li>
</#list>
</ul>
</body>
</html>
java代码
@Test
public void template1() {
List<String> list = new ArrayList<String>();
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");
}
展示效果
可以看到在html生成成功, 打开按照if 判断的形式循环展示 (-_- 完美)
include 指令
该指令表示导入其他的文件或者freemarker文件, 一般用于导入公共文件, 如网站的头部, 公共资源文件,版权信息等
语法
//这里的path代表文件的路径
<#include path>
import 指令
该指令类似于include, 不同的是import导入进来后, 可以在该文件中使用被导入文件的宏组件
语法
// path 文件路径 p 别名
<#import path as p>
小实例: include 和 import 展示其区别
setting 指令
该指令用于动态设置freeMarker的运行环境。
语法
<#setting name=value>
name的取值范围包括:
- locale: 指定该模板所用的国家/语言选项
- number_format: 定格式化输出数字的格式
- boolean_format: 指定两个布尔值的语法格式,默认值是true,false
- date_format, time_format, datetime_format: 指定显示的时间格式
- 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包
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.23</version>
</dependency>
<!-- ui.freemarker -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
spring-mvc.xml
<!--视图解析器-->
<!--配置试图解析器 -->
<bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
<property name="order" value="1"></property>
<property name="suffix" value=".ftl"></property>
<property name="contentType" value="text/html;charset=utf-8"></property>
<property name="viewClass">
<value>org.springframework.web.servlet.view.freemarker.FreeMarkerView</value>
</property>
<property name="requestContextAttribute" value="request"></property>
</bean>
<!--加载freemarker属性 -->
<bean id="propertySetting" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<list>
<value>classpath:freemarker.properties</value>
</list>
</property>
</bean>
<!--freemarker配置 -->
<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="templateLoaderPath">
<value>/WEB-INF/ftl/</value>
</property>
<property name="freemarkerSettings" ref="propertySetting"></property>
</bean>
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简单的内容, 更多相关内容参考
预告
通过本章节Freemarker算是简单入门, 那么下一节通过实战来加深对Freemarker的印象
实战演练, Freemarker + MyBatis 配合开发我们的代码生成器