Freemarker笔记
Day01笔记
一、Freemarket概念、特点、环境搭建
1.Freemarket概念
FreeMarker是一个模板引擎,一个基于模板生成文本输出的通用工具,用纯Java编写。 FreeMarker 被设计用来生成HTML Web 页面,特别是基于 MVC 模式的应用程序虽然FreeMarker 具有一些编程的能力,但通常由 Java 程序准备要显示的数据。
FreeMarker 不是一个 Web 应用框架,而适合作为 Web 应用框架一个组件。 FreeMarker 与容器无关,因为它并不知道 HTTP 或 Servlet;FreeMarker 同样可以应用于非 Web 应用程序环境。FreeMarker 更适合作为 Model2 框架(如 Struts)的视图组件,你也可以在模板中使用 JSP 标记库。
2.FreeMarker特性
1)通用目标
能够生成各种文本:HTML、XML、RTF、Java 源代码等等
易于嵌入到你的产品中:轻量级;不需要 Servlet 环境
插件式模板载入器:可以从任何源载入模板,如本地文件、数据库等
你可以按你所需生成文本:保存到本地文件;作为 Email 发送;从 Web 应用程序发送它返回给 Web 浏览器
2)强大的模板语言
所有常用的指令:include、if/elseif/else、循环结构
在模板中创建和改变变量 几乎在任何地方都可以使用复杂表达式来指定值命名的宏,可以具有位置参数和嵌套内容
名字空间有助于建立和维护可重用的宏库,或将大工程分成模块,而不必担心名字冲突
输出转换块:在嵌套模板片段生成输出时,转换 HTML 转义、压缩、语法高亮等等;你可以定义自己的转换
3)通用数据模型
FreeMarker 不是直接反射到Java 对象,Java 对象通过插件式对象封装,以变量方式在模板中显示你可以使用抽象(接口)方式表示对象(JavaBean、XML 文档、SQL 查询结果集等等),告诉模板开发者使用方法,使其不受技术细节的打扰
4)智能的国际化和本地化
字符集智能化(内部使用 UNICODE)
数字格式本地化敏感日期和时间格式本
地化敏感非 US 字符集可以用作标识(如变量名)
多种不同语言的相同模板
5)强大的XML处理能力
<#recurse>和<#visit>指令(2.3 版本)用于递归遍历 XML 树。在模板中清楚和直接的访问 XML 对象模型。开源论坛 JForum 就是使用了 FreeMarker 做为页面模板。
3.Freemarker环境搭建
1)新建web工程
2)添加依赖坐标
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.23</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
</dependency>
<plugins>
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.2.1.v20140609</version>
</plugin>
</plugins>
3)添加web.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="3.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<servlet>
<servlet-name>freemarker</servlet-name>
<servlet-class>freemarker.ext.servlet.FreemarkerServlet</servlet-class>
<init-param>
<param-name>TemplatePath</param-name>
<param-value>/</param-value>
</init-param>
<init-param>
<param-name>default_encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>freemarker</servlet-name>
<url-pattern>*.ftl</url-pattern>
</servlet-mapping>
</web-app>
4)编写servlet
@WebServlet("/f01")
public class F01 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/**
* 添加Model S数据
*/
req.setAttribute("msg","Hello Freemarker");
req.getRequestDispatcher("template/f01.ftl").forward(req,resp);
}
}
5)新建模板文件.ftl
webapp/template/f01.ftl
<!--
1.html 所有标签 在freemarker 中均适用 语法一致
2.js css 均适用 语法一致
-->
<h1>${msg}</h1>
6)访问
http://localhost:8080/f01
二、Freemarker基本数据类型
布尔 日期 数值 string 序列(list 数组 set) hash
1.布尔
<#--布尔值
布尔值 在freemarker 中不能直接输出 如果输出 需要进行转化 ?c ?string
-->
${isDel?string("yes","no")} || ${isDel?c} || ${isDel?string}
2.日期
<#--日期
日期 在freemarker 中不能直接输出 如果输出 需要进行转化 ?date ?time ?dateTime ?string
-->
<hr/>
${createTime?date} || ${createTime?datetime} || ${createTime?time} || ${createTime?string("yyyy年MM月dd日 HH:mm:ss")}
3.数值
<#--数值
百分比 美元 小数位数
-->
${age} || ${salary} || ${salary?c} || ${salary?string.currency} || ${avg?string.percent} ||
${avg?string["0.##"]}
4.字符串String
<#--字符串 string
防止value 空值处理
${model!}:当model 数据为空时 默认使用空串显示 !"xxx" 也可以使用默认值 xxx
??:判断model 数据是否为空 返回值为 布尔值
-->
${name} || ${admin!}|| ${admin!"test"} ||
${(abc??)?string}
<hr/>
<#--
字符串首字母大写 字符串转为大写|小写 字符串结尾 包含
-->
${msg?cap_first} || ${msg?upper_case} ||
${msg?lower_case}
|| ${(msg?ends_with("freemarker"))?c}
|| ${(msg?contains("ee"))?c} || ${msg?capitalize}
<#-- 字符串 转为 日期-->
<#assign someDate="2020-01-03" ? date> ||
${someDate} || ${msg?ensure_ends_with("ker")}
5.序列
req.setAttribute("taobao", Arrays.asList("衣服","装饰品","鞋子","帽子"));
req.setAttribute("star",new String[]{"杨洋","郑爽","肖战","王嘉尔"});
req.setAttribute("users",Arrays.asList(new User(1,"hhh",19),
new User(2,"sss",18),
new User(3,"qqq",17)));
<#--
序列:
list set 数组
-->
<#--集合list-->
<#list taobao as tb>
${tb}<br/>
</#list>
<hr/>
<#--数组-->
<#list star as st>
${st} ||
</#list>
${star?join(",")}
<hr/>
<#--list-->
<#list users?sort as user>
${user.id} || ${user.name} ||${user.age}
</#list>
6.hash
//hash
Map<String,String> map=new HashMap<>();
map.put("sh","上海");
map.put("hz","杭州");
map.put("nc","南昌");
req.setAttribute("city",map);
<#--
hash map集合
-->
<hr/>
<#list city?keys as key>
${key} || ${city[key]}<br/>
</#list>
三、Freemarker常见指令
<#--
freemarker 常见指令
assign 变量定义指令
if elseif else 逻辑判断
macro 自定义指令 类似方法
nested 占位指令 通常配置macro 使用
import ftl 文件导入
include 包含指令 包含页面内容
function 函数
return 返回值
-->
1.assign 变量定义指令
<#assign str="hello" names=["admin","test"]>
${str} || ${names?join(",")}
2.if elseif else 逻辑判断
<#assign age=10>
<#if age gt 0 && age lte 6>
儿童
<#elseif age gt 6 && age lte 12>
青少年
<#elseif age gt 12 && age lte 18>
少年
<#else>
成年人
</#if>
<hr/>
<#if user??>
数据存在
<#else>
数据不存在
</#if>
<#if user??>
数据存在
<#else>
数据不存在
</#if>
3.macro 自定义指令 类似方法
<#macro top>
肯定会来房间开始咯评分外婆福克斯父接口
</#macro>
<br>
<#--使用-->
<#--<@top></@top><br>-->
<@top></@top>
<br>
<#macro queryUserByUserName uname>
查询用户根据用户名 -->${uname}
</#macro>
<@queryUserByUserName uname="admin"></@queryUserByUserName><br>
<@queryUserByUserName uname="test"></@queryUserByUserName>
<hr>
<#macro querUserByParams uname upwd phone>
多条件查询用户-->${uname} || ${upwd} || ${phone}
</#macro>
<@querUserByParams uname="admin" upwd="123456" phone="123334778999"></@querUserByParams>
4.nested 占位指令 通常配置macro使用
<#--
占位符几个,内容就重复几遍
-->
<#macro test>
xxxxxxxxx <#nested><#nested>
</#macro>
<@test> jfkldsfj sk</@test>
5.list 遍历 循环
<#--
打印9*9乘法表打印
-->
<#macro cfb>
<#list 1..9 as i>
<#list 1..i as j>
${i}*${j}=${i*j}
</#list>
<br/>
</#list>
</#macro>
<@cfb></@cfb>
<#macro cfb02 num>
<#list 1..num as i>
<#list 1..i as j>
${i}*${j}=${i*j}
</#list>
<br/>
</#list>
</#macro>
<@cfb02 num=7></@cfb02>
6.import ftl文件导入
<#--
引入别的文件.ftl
-->
<#import "common.ftl" as cm>
<#import "base.ftl" as bs>
<@cm.cfb02 num=6></@cm.cfb02>
<@bs.test>
哈哈哈哈哈哈
</@bs.test>
引入文件:
<#macro test>
xxxxxxxxx <#nested> <#nested> <#nested>
</#macro>
<#macro cfb02 num>
<#list 1..num as i>
<#list 1..i as j>
${i}*${j}=${i*j}
</#list>
<br/>
</#list>
</#macro>
7.include 包含指令 包含页面内容
<#--
引入HTML文件
-->
<#include "base.html">
<hr/>
<#include "技术分享.txt">
包含文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
网站菜单文件
</body>
</html>
<!--
技术分享.txt
1.概念解释 & 代码
2.如何能够说明白你要讲的内容?
Java8 Lambda
Java7
接口有且仅有一个抽象方法 匿名函数实现
Java8 引入函数式接口:接口有且仅有一个抽象方法
简化匿名函数代码 引入 lambda 表达式
() -> {}
-->
8.function 函数 return 返回值
<#function avg x y>
<#return (x+y)/2>
</#function>
${avg(10,20)}
四、Freemarker页面静态化
1.过程
Freemarker **是一种基于模板的、用来生成输出文本的通用工具,所以我们必须要定制符合自己业务的模板,然后生成自己的 html 页面。**Freemarker 是通过freemarker.template.Configuration 这个对象对模板进行加载的(它也处理创建和缓存预解析模板的工作),然后我们通过 getTemplate 方法获得你想要的模板,有一点要记住freemarker.template.Configuration 在你整个应用必须保证唯一实例。
@WebServlet("/f04")
public class F04 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//实例化模版配置对象
Configuration configuration = new Configuration();
//以及模板设置加载模板的上下文 以及模板存放路径
configuration.setServletContextForTemplateLoading(getServletContext(),"/template");
//设置编码
configuration.setDefaultEncoding("utf-8");
//加载模板文件 获取模板对象
Template template=configuration.getTemplate("news.ftl");
//写入内容
Map<String,Object> map=new HashMap<>();
map.put("title","自我介绍");
map.put("source","自学网");
map.put("pubTime",new Date());
map.put("content","随着电商平台的兴起,也拉动了快递行业的快速发展,有数据显示,快递业务量从80年代的153万件,提升到去年的507.1亿件,预计到今年快递数量将超过600亿件。" +"\n" +
"\n" +
" 而根据前段时间,胡润研究院对外发布了《2019一季度胡润大中华区独角兽指数》,数据显示,在国内物流行业中,以估值大小进行排名,排在前5位的分别为菜鸟网络(1000亿)、京东物流(800亿)、满帮(400亿)、达达-京东到家(300亿)和跨越速运(200)。");
//得到路径
String basePath =req.getSession().getServletContext().getRealPath("/");
File file = new File(basePath + "/html");
if(!(file.exists())){
file.mkdir();
}
//以毫秒为文件名
String fileName=System.currentTimeMillis()+".html";
//写入
Writer writer=new FileWriter(new File(file,fileName));
try {
template.process(map,writer);
System.out.println("新闻创建成功!");
} catch (TemplateException e) {
e.printStackTrace();
}finally{
//刷出
writer.flush();
//关闭
writer.close();
}
}
}
news.ftl文件:
<h1>${title}</h1>
<p>
新闻来源:${source} <span>发布时间:${pubTime?string("yyyy年MM月dd日 HH:mm:ss")}</span>
</p>
<p>
${content}
</p>
五、SSM集成Freemarker
1.SSM集成Freemarker配置
添加依赖坐标
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support </artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<!-- Template Language -->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.21</version>
</dependency>
视图配置
servlet-context.xml
<!-- 视图配置 -->
<bean id="freemarkerConfig"
class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="templateLoaderPath" value="/WEB-INF/views/" />
<property name="defaultEncoding" value="UTF-8" />
</bean>
<bean 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>
2.jetty启动测试
@Controller
public class TestController {
@RequestMapping("test")
public String test(Model model){
model.addAttribute("msg","hello ssm$freemarker");
return "test";
}
}
wEB-INF/views/test.ftl
${msg!}
访问:http://localhost:8080/ssm/test